Metaclasses seem to be an obscure, misunderstood area of Python’s object model. Here is a simple example that I’ve used to both understand and explain what a metaclass is a how it can be used.
This code snippet was spawned from a colleague’s query.
“What would be the most pythonic way to override a class type’s string representation?”
Expressed in code he wanted a new-style class type A to behave like
>>> A <class '__main__.A'> >>> str(A) 'Hello World'
Unfotunately overriding A’s __str__ method
>>> class A(object): ... def __str__(self): ... return "Hello World" ... >>> A <class '__main__.A'> >>> str(A) "<class '__main__.A'>" >>> str(A()) 'Hello World' >>>
only overrides the string representation of instances of A rather than the type A.
The solution to the problem leads us to metaclasses. My colleague’s conundrum can be solved by creating a new-style class with base type and a __str__ method. This acts to override the __str__ method of A’s type rather than instances of A.
>>> class meta_A(type): ... def __str__(cls): ... return "Hello World" ... >>> class A(object): ... __metaclass__ = meta_A ... >>> A <class '__main__.A'> >>> str(A) 'Hello World' >>> str(A()) '<__main__.A object at 0x10049e710>'
Thus we have a pythonic mechanism for overriding the string representation of a class type.
Note that there is new syntax in Python 3.0 for specifying a metaclass.
>>> class A(metaclass=meta_A): ... pass ...