The __metaclass__ attribute
Customizing class creation #
By default, new-style classes are constructed using type. A class
definition is read into a separate namespace and the value of class
name is bound to the result of
type(name, bases, dict), where name
is the name of the class, bases is a list of base classes, and
dict is a namespace populated by the class statement.
- Modifying the class dictionary prior to the class being created.
- Returning an instance of another class — essentially performing the role of a factory function.
This variable can be any callable accepting arguments for name, bases, and dict. Upon class creation, the callable is used instead of the built-in type. New in version 2.2.
The appropriate metaclass is determined by the following precedence rules:
dict['__metaclass__']exists, it is used.
- Otherwise, if there is at least one base class, its metaclass is used (this looks for a __class__ attribute first and if not found, uses its type). Note that this rule kicks in if you’re inheriting from object.
- Otherwise, if a global variable named __metaclass__ exists, it is used.
- Otherwise, the old-style, classic metaclass (types.ClassType) is used.
The potential uses for metaclasses are boundless. Some ideas that have been explored including logging, interface checking, automatic delegation, automatic property creation, proxies, frameworks, and automatic resource locking/synchronization.