What can be done with metaclasses that can't be in any other way?
Alex Martelli told that there are tasks that can't be achieved without metaclasses here Python metaclasses vs class decorators I'd like to know which are?
A metaclass is most commonly used as a class-factory. When you create an object by calling the class, Python creates a new class (when it executes the 'class' statement) by calling the metaclass.
Metaclasses give us the ability to write code that transforms, not just data, but other code, e.g. transforming a class at the time when it is instantiated. In the example above, our metaclass adds a new method automatically to new classes that we define to use our metaclass as their metaclass.
A metaclass in Python is a class of a class that defines how a class behaves. A class is itself an instance of a metaclass. A class in Python defines how the instance of the class will behave. In order to understand metaclasses well, one needs to have prior experience working with Python classes.
Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have attributes attached to it for maintaining its state.
Metaclasses are indispensable if you want to have class objects (as opposed to instances of class objects) equipped with "special customized behavior", since an object's behavior depends on special methods on the type of the object, and a class object's type is, exactly a synonym for, the metaclass.
For example, if you want a class object X such that "print X" emits "Time is now 8:46am" (at 8:46 am, or, more generally, the current time) this must mean that type(x)
(AKA X's metaclass) has a special custom __str__
method -- and similarly (with the various applicable special-methods) if you want to give meaning to expressions such as X + Y
where X and Y are both class objects, or X[23]
(where X, again, is a class object), and so forth.
Most other customization tasks are now (in Python 2.6 or better) easier to implement with a class decorator, which can alter a class object right after the end of the class
statement. There are a few more cases where this is not feasible because the alterations must be made very early on if they are to have any effect (e.g., setting or altering __slots__
).
In Python 3, metaclasses gain one extra little bit of usefulness: a metaclass can now optionally specify the mapping object to be populated during the execution of the class
statement's body (by default, it's a normal dict
). This allows the order of name bindings in the class body to be preserved and used (while the normal dict
loses order), which is sometimes nice when the class must have "fields" in a certain specific order (e.g. to map 1:1 onto a C struct
, a row in a CSV file or DB table, and the like) -- in Python 2.* this had to be redundantly specified (typically with an extra class attribute that's a sequence and thus does preserve order), and this feature of Python 3 metaclasses allows the redundancy to be removed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With