Metaclasses

https://docs.python.org/3/reference/datamodel.html

INTRODUCTION

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']