In Python, a metaclass is a class that defines the behavior of other classes. It is used to customize the behavior of class creation and to add special behaviors to classes. A metaclass is a class that is used to create other classes. In other words, it is a class of classes.
The type() function is the built-in metaclass in Python. When you create a class using the
class keyword, Python internally calls the type() function to create the class object.
Here's an example of how to create a metaclass:
class MyMeta(type):
def __new__(cls, name, bases, attrs):
print("Creating class", name)
attrs["my_attr"] = "hello"
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=MyMeta):
def __init__(self, value):
self.value = value
In this example, we define a metaclass called MyMeta. This metaclass overrides the
__new__() method, which is called by Python when creating a new class. In the
__new__() method, we print a message indicating that we are creating a new class, and we add a new attribute called
my_attr to the class.
We then define a new class called MyClass and set its metaclass to
MyMeta using the metaclass argument in the class definition. When we create an instance of
MyClass, the __new__() method of MyMeta is called and adds the
my_attr attribute to the class.
When we run this code, we should see the message "Creating class MyClass" printed to the console.
A metaclass is the class of a class. Like a class defines how an instance of the class behaves, a metaclass defines how a class behaves. A class is an instance of a metaclass.
While in Python you can use arbitrary callables for metaclasses (like Jerub shows), the more useful approach is actually to make it an actual class itself. 'type' is the usual metaclass in Python. In case you're wondering, yes, 'type' is itself a class, and it is its own type. You won't be able to recreate something like 'type' purely in Python, but Python cheats a little. To create your own metaclass in Python you really just want to subclass 'type'.
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.
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.
However, metaclasses actually define the type of a class, not just a factory for it, so you can do much more with them. You can, for instance, define normal methods on the metaclass. These metaclass-methods are like classmethods, in that they can be called on the class without an instance, but they are also not like classmethods in that they cannot be called on an instance of the class. type.__subclasses__() is an example of a method on the 'type' metaclass. You can also define the normal 'magic' methods, like __add__, __iter__ and __getattr__, to implement or change how the class behaves.
Here's an aggregated example of the bits and pieces:
def make_hook(f): """Decorator to turn 'foo' method into '__foo__'""" f.is_hook = 1 return f class MyType(type): def __new__(cls, name, bases, attrs): if name.startswith('None'): return None # Go over attributes and see if they should be renamed. newattrs = {} for 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, to autogenerate the classname as well as the 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 # Will 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) # Will unregister the class Example.unregister() inst = Example(10) # Will fail with an AttributeError #inst.unregister() print inst + inst class Sibling(MyObject): pass ExampleSibling = Example + Sibling # ExampleSibling is now a subclass of both Example and Sibling (with no # content of its own) although it will believe it's called 'AutoClass' print ExampleSibling print ExampleSibling.__mro__
Join MindStick Community
You need to log in or register to vote on answers or questions.
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy.
In Python, a metaclass is a class that defines the behavior of other classes. It is used to customize the behavior of class creation and to add special behaviors to classes. A metaclass is a class that is used to create other classes. In other words, it is a class of classes.
The type() function is the built-in metaclass in Python. When you create a class using the class keyword, Python internally calls the type() function to create the class object.
Here's an example of how to create a metaclass:
In this example, we define a metaclass called MyMeta. This metaclass overrides the __new__() method, which is called by Python when creating a new class. In the __new__() method, we print a message indicating that we are creating a new class, and we add a new attribute called my_attr to the class.
We then define a new class called MyClass and set its metaclass to MyMeta using the metaclass argument in the class definition. When we create an instance of MyClass, the __new__() method of MyMeta is called and adds the my_attr attribute to the class.
When we run this code, we should see the message "Creating class MyClass" printed to the console.