https://docs.python.org/3/reference/datamodel.html
By default, classes are constructed using 'type()'. The class body is executed in a new namespace and the class name is bound locally to the result of type(name, bases, namespace).
# Syntax. # type(object) return the type of an object, like object.__class__ (one argument) # type(name, bases, namespace) return a new type object (three arguments) MyClass = type("MyClass", (), {}) # a dynamic form of the 'class' statement # the same as class MyClass: pass
MyClass = type("MyClass", (BaseClass,), {'attribute' : 42}) # the same as class MyClass(BaseClass): attribute = 42
class Meta(type): # inheritence from 'type' # __init__ is optional def __new__(mcls, name, bases, namespace): namespace['foo'] = 'Meta was here' # 'foo' is added to the class namespace, # before the class 'name' is created cls = type.__new__(mcls, name, bases, namespace) return cls class C(metaclass=Meta): pass print(C.foo) # Meta was here print(dir(C)) # 'foo' is here print(C.__dict__['foo']) # Meta was here
models = {} class ModelMetaclass(type): def __new__(mcls, name, bases, namespace): cls = type.__new__(mcls, name, bases, namespace) models[name] = cls return cls class Model(metaclass=ModelMetaclass): pass class A(Model): pass class B(A): pass print(list(models)) # ['Model', 'A', 'B']