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.

metaclass diagram

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

Popular posts from this blog

neo4j - finding mutual friends in a cypher statement starting with three or more persons -

php - How to remove letter in front of the word laravel -

minify - Minimizing css files -