8.5. Metaprogramming Class Factory
Metaclasses allow you to do 'extra things' when creating a class
Allow customization of class instantiation
Most commonly used as a class-factory
Registering the new class with some registry
Replace the class with something else entirely
Inject logger instance
Injecting static fields
Ensure subclass implementation
Metaclasses run when Python defines class (even if no instance is created)
The potential uses for metaclasses are boundless. Some ideas that have been explored include enum, logging, interface checking, automatic delegation, automatic property creation, proxies, frameworks, and automatic resource locking/synchronization. [#pydocclassobject]_
8.5.1. Recap
Functions are instances of a
function
class
Before we go into metaclasses, let's recap a fact about functions. Consider a typical function definition:
>>> def add(a, b):
... return a + b
Functions are instances of a function
class:
>>> type(add)
<class 'function'>
By extent they are effectively an instance of a type
class.
8.5.2. Class Creation
type(str, tuple, dict)
will create a class object
We need to recall how classes are created:
>>> User = type('User', (), {})
8.5.3. Function Based Metaclass
Metaclass is a function which returns a class
>>> def mytype(clsname, bases, attrs):
... return type('User', (), {})
Then we can use it, instead of a regular type()
:
>>> User = mytype('User', (), {})
8.5.4. Usage
Function based metaclass:
>>> def mytype(clsname, bases, attrs):
... return type('User', (), {})
>>>
>>> class User(metaclass=mytype):
... pass
Both are equivalent and will create a class object.