makeClass (
name,
bases,
dict,
)
makeClass(name, bases, dict) - enhanced class creation
Automatically generates a metaclass that satisfies metaclass constraints
inherited from the supplied base classes, and then calls it to create a
new class. It can be used as a __metaclass__ value, or can be directly
called as a substitute to using new.classobject() to dynamically create
classes.
If the supplied dictionary contains a __metaclasses__ entry, it will be
taken to be a sequence of metaclasses which should take first priority in
the base classes of the generated metaclass. The next highest priority is
given to the dictionary's __metaclass__ entry, if any, and then priority
is according to the order of the base classes which introduce the metaclass
constraints.
ClassType (the "classic" class type) is automatically excluded from the
constraints, as is the makeClass function itself (just in case you used
the function as an explicit metaclass). makeClass() will only return
a "classic" class if all the base classes are classic, and no
__metaclass__ or __metaclasses__ entries supply any non-classic
types. Effectively, makeClass() fully supports the three most popular
Python metatypes: "classic classes", "new-style types", and
ExtensionClass . You cannot, however, combine ExtensionClasses with
new-style types, because their root metatypes are different. That is,
type(type) is type , and type(ExtensionClass) is ExtensionClass . There
may be other ways to create illegal metatype combinations, but they should
be detected and result in a TypeError.
Generated metaclasses are cached for reuse, and they are automatically
given classnames which are the concatenation of their base metaclasses'
names. So if you set __metaclasses__ to ThreadSafe, Persistent
(or if your bases are instances of ThreadSafe and Persistent ), the
derived metaclass will be called ThreadSafe_Persistent . That is,
the return from makeClass() will be of type (have a __class__ of)
ThreadSafe_Persistent .
Metaclasses are derived according to the algorithm in the book "Putting
Metaclasses to Work", by Ira R. Forman and Scott H. Danforth. It, and
Guido's metaclass tutorial for Python 2.2, are highly recommended reading
for making the best use of this capability. But a brief word to the wise:
Write your metaclasses co-operatively! Don't assume that your
metaclass will be the first or last one to handle a particular
method call.
In general, when programming with new-style classes, don't assume
you know what the inheritance order is. Always use 'super()';
super() is your friend. :) Remember that your immediate base
class today, may have other classes sandwiched between you and it
tomorrow, if one of your subclasses so desires!
|