0

I want to ensure that any class that is derived from my class overrides certain methods. If they are not overridden I want to raise a NotImplementedError as soon as possible after compiling begins, rather than when one of the methods are called.

I've found that I can do it with a metaclass like so:

class MetaBaseClass(type):
    # list of method names which should be overridden
    to_override = ['method_a', 'method_b']

    def __init__(cls, name, bases, dct):
        for methodName in cls.to_override:
            if methodName not in dct:
                 raise NotImplementedError('{0} must override the {1} method'.format(name, methodName))
        super(MetaBaseClass, cls).__init__(name, bases, dct)

class BaseClass(object):

    __metaclass__ = MetaBaseClass

    def method_a(self):
        pass

    def method_b(self):
        pass

This will raise the error at class definition time if method_a or method_b aren't overridden by class derived from BaseClass.

Is there a better way to do this?

Griffin
  • 13,184
  • 4
  • 29
  • 43
  • 2
    FYI That's not compile time, it's class definition time, which is usually module import time. But a class can also be defined conditionally (so this test wouldn't run either) or dynamically, e.g. inside functions called at any time during the application run. –  Jun 08 '14 at 11:00
  • @delnan Thanks I suppose I mean I want to raise the error as soon as possible. I'll fix my wording. – Griffin Jun 08 '14 at 11:06

1 Answers1

0

Why not use abstractmethod.

from abc import abstractmethod, ABCMeta
class BaseClass(object):

    __metaclass__ = ABCMeta

    @abstractmethod
    def method_a(self):
        pass
    @abstractmethod
    def method_b(self):
        pass

class Inherit(BaseClass):
    pass

You will get an error as soon as a user tries to instantiate the Inherit class.

i = Inherit()
TypeError: Can't instantiate abstract class Inherit with abstract methods method_a, method_b
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • Thanks for your answer. I didn't know about `abstractmethod`. But it would seem that my method raises the error sooner than this will. I'm really trying to save as much time with debugging as possible. – Griffin Jun 08 '14 at 11:41
  • I think a simple `if __name__== "__main__" Inherit() etc..` would do the same thing. – Padraic Cunningham Jun 08 '14 at 12:00