Python Metaclass
Python Metaclass
In backtrader py3.py class, there is a magic method which is used extensively by the code.
# This is from Armin Ronacher from Flash simplified later by six
def with_metaclass(meta, *bases):
"""Create a base class with a metaclass."""
# This requires a bit of explanation: the basic idea is to make a dummy
# metaclass for one level of class instantiation that replaces itself with
# the actual metaclass.
class metaclass(meta):
def __new__(cls, name, this_bases, d):
return meta(name, bases, d)
return type.__new__(metaclass, str('temporary_class'), (), {})The with_metaclass() function makes use of the fact that metaclasses are
a) inherited by subclasses, and
b) a metaclass can be used to generate new classes and
c) when you subclass from a base class with a metaclass, creating the actual subclass object is delegated to the metaclass.
d)
type.__new__(metaclass, 'temporary_class', (), {})uses themetaclassmetaclass to create a new class object namedtemporary_classthat is entirely empty otherwise.type.__new__(metaclass, ...)is used instead ofmetaclass(...)to avoid using the specialmetaclass.__new__()implementation that is needed for the slight of hand in a next step to work.If
metaclass(...)is used there will be an extratemporary_classbase class.# print(Foo.__mro__) (<class 'metaclass_tests.Foo'>, <class 'metaclass_tests.temporary_class'>, <class 'object'>)
It effectively creates a new, temporary base class with a temporary metaclass metaclass that, when used to create the subclass swaps out the temporary base class.
and it could be used as
At
L1a class namedtemporary_classhas been created frommetaclassand assigned to a local variable also namedtemporary_class.At
L2when thetemporary_classis used as the base class, creating the actualFooclass will be delegated to the temporary_classthe
def __new__(cls, name, this_bases, d)function will be called andmetaclass,Foo,temporary_classand{}will be passed in. Thenmeta(name, bases, d)will be used to create the actualFooclass. Note that as no instance ofmetaclassis return in the__new__method, the__init__method inside themetaclasswill never be called.
Tests
Reference
Last updated
Was this helpful?