oop - What is a metaclass in Python? -
what metaclasses? use them for?
a metaclass class of class. class defines how instance of class behaves, metaclass defines how class behaves. class instance of metaclass.
while in python can use arbitrary callables metaclasses (like jerub shows), more useful approach make actual class itself. type usual metaclass in python. in case you're wondering, yes, type class, , own type. won't able recreate type purely in python, python cheats little. create own metaclass in python want subclass type.
a metaclass commonly used class-factory. create instance of class calling class, python creates new class (when executes 'class' statement) calling metaclass. combined normal __init__ , __new__ methods, metaclasses therefore allow 'extra things' when creating class, registering new class registry, or replace class else entirely.
when class statement executed, python first executes body of class statement normal block of code. resulting namespace (a dict) holds attributes of class-to-be. metaclass determined looking @ baseclasses of class-to-be (metaclasses inherited), @ __metaclass__ attribute of class-to-be (if any) or __metaclass__ global variable. metaclass called name, bases , attributes of class instantiate it.
however, metaclasses define type of class, not factory it, can more them. can, instance, define normal methods on metaclass. these metaclass-methods classmethods, in can called on class without instance, not classmethods in cannot called on instance of class. type.__subclasses__() example of method on type metaclass. can define normal 'magic' methods, __add__, __iter__ , __getattr__, implement or change how class behaves.
here's aggregated example of bits , pieces:
def make_hook(f): """decorator turn 'foo' method '__foo__'""" f.is_hook = 1 return f class mytype(type): def __new__(cls, name, bases, attrs): if name.startswith('none'): return none # go on attributes , see if should renamed. newattrs = {} attrname, attrvalue in attrs.iteritems(): if getattr(attrvalue, 'is_hook', 0): newattrs['__%s__' % attrname] = attrvalue else: newattrs[attrname] = attrvalue return super(mytype, cls).__new__(cls, name, bases, newattrs) def __init__(self, name, bases, attrs): super(mytype, self).__init__(name, bases, attrs) # classregistry.register(self, self.interfaces) print "would register class %s now." % self def __add__(self, other): class autoclass(self, other): pass return autoclass # alternatively, autogenerate classname class: # return type(self.__name__ + other.__name__, (self, other), {}) def unregister(self): # classregistry.unregister(self) print "would unregister class %s now." % self class myobject: __metaclass__ = mytype class nonesample(myobject): pass # print "nonetype none" print type(nonesample), repr(nonesample) class example(myobject): def __init__(self, value): self.value = value @make_hook def add(self, other): return self.__class__(self.value + other.value) # unregister class example.unregister() inst = example(10) # fail attributeerror #inst.unregister() print inst + inst class sibling(myobject): pass examplesibling = example + sibling # examplesibling subclass of both example , sibling (with no # content of own) although believe it's called 'autoclass' print examplesibling print examplesibling.__mro__ 
Comments
Post a Comment