In Python (3+) it is impossible to create a class which is not a subclass of object
. This means that the protocols associated with the class and instances of the class are tightly bound to object
. Metaclasses provide a way to extend this so as to have additional domain-specific protocols.
The snippet below shows how this may be accomplished by overriding the type.__init__()
during metaclass definition. The metaclass will have a collection of methods that will be hooked into the class once it is created. These methods may then be used to implement the domain-specific protocols.
# the metaclass class Meta(type): def __init__(self, name, bases, class_dict): # since this is init the class has already been created # we introduce some arbitrary 'fire' protocol which will be invoked # using some 'fire()' function self.__fire__ = self._fire type.__init__(self, name, bases, class_dict) def _fire(self, *args, **kwargs): print('args: ', args) print('kwargs: ', kwargs) def fire(obj, *args, **kwargs): obj.__fire__(*args, **kwargs) # now we can create classes based on this metaclass class X(object, metaclass=Meta): pass x = X() # their MRO still includes object print('X.__mro__:', X.__mro__) # both the class and instances will support the fire protocol print('dir(x):', dir(x)) print('dir(X):', dir(X)) # even subclasses will and their instances will support the fire protocol class XX(X): pass xx = XX() print('XX.__mro__:', XX.__mro__) print('dir(xx):', dir(xx)) print('dir(XX):', dir(XX)) # they are NOT of type 'type' print('type(X)', type(X)) print('type(XX)', type(XX))