This decorator wraps the class's __init__ function to check that provided set of methods is present on the instantiated class. This is useful for avoiding inheritance in mix-in classes. We can inherit directly from object and still make it clear what methods we expect in other classes to be combined with the mix-in.
Requires at least Python 2.6, which added class decorators.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
def require_methods(*method_args): """Class decorator to require methods on a subclass. Example usage ------------ @require_methods('m1', 'm2') class C(object): 'This class cannot be instantiated unless the subclass defines m1() and m2().' def __init__(self): pass """ def fn(cls): orig_init = cls.__init__ def init_wrapper(self, *args, **kwargs): for method in method_args: if (not (method in dir(self))) or \ (not callable(getattr(self, method))): raise Exception("Required method %s not implemented" % method) orig_init(self, *args, **kwargs) cls.__init__ = init_wrapper return cls return fn
Avoiding inheritance makes mix-in classes much more compose-able. One way to do this is to have each mix-in inherit from object and declare any methods they expect to be present in the concrete class.
For more context, see the presentation linked at http://blog.genforma.com/2011/05/27/talk-on-python-mix-in-classes/