Thursday, March 12, 2015

Meta class in python

A class is an instance of a metaclass. Like a class defines how an instance of the class behaves, a metaclass defines how a class behaves. A metaclass is most commonly used as a class-factory. Like you create an instance of the class by calling the class, Python creates a new class (when it executes the 'class' statement) by calling the metaclass. Combined with the normal __init__ and __new__ methods, metaclasses therefore allow you to do 'extra things' when creating a class, like registering the new class with some registry, or even replace the class with something else entirely.

A metaclass is any callable that takes parameters for:
  1. the class name
  2. the class's bases (parent classes)
  3. the class's attributes (methods and variables)
The type type is the default metaclass in Python.

When the 'class' statement is executed, Python first executes the body of the 'class' statement as a normal block of code. The resulting namespace (a dict) holds the attributes of the class-to-be. The metaclass is determined by looking at the baseclasses of the class-to-be (metaclasses are inherited), at the __metaclass__ attribute of the class-to-be (if any) or the '__metaclass__' global variable. The metaclass is then called with the name, bases and attributes of the class to instantiate it.

In the following example, we will change the doc string of a function in a class using meta class.

def make_class(classname, parent, attributes):
    function = attributes['some_function']
    function.__doc__ = "
%s for %s"%(function.__doc__, function.func_name)
    cls = type(classname, parent, attributes)
    return cls

class A:
    __metaclass__ = make_class

    def some_function():
        """

        Some random doc string
        """
        pass

obj = A()
print obj.some_function.__doc__





PS: Although above example is simple one, Metaclasses can make code incredibly difficult to understand. Only use them when you really need them.



No comments:

Post a Comment