9 Основные метаклассы

Когда type вызывается с тремя аргументами он ведет себя как (мета) класс она есть, и создает новый экземпляр, то есть. это производит новый класс / тип.

 Dummy = type('OtherDummy', (), dict(x=1))
Dummy.__class__              # <type 'type'> 
Dummy().__class__.__class__  # <type 'type'> 

 

Можно создать подкласс type для создания метакласса.

 class mytype(type):
    def __init__(cls, name, bases, dict):
        # call the base initializer
        type.__init__(cls, name, bases, dict)

        # perform custom initialization...
        cls.__custom_attribute__ = 2

 

Теперь у нас есть новый пользовательский mytype метакласса , который может быть использован для создания классов в том же порядке , как type .

 MyDummy = mytype('MyDummy', (), dict(x=2))
MyDummy.__class__              # <class '__main__.mytype'>
MyDummy().__class__.__class__  # <class '__main__.mytype'>
MyDummy.__custom_attribute__   # 2

 

Когда мы создаем новый класс , используя class ключевого слово метакласса по умолчанию выбирается на основе на BASECLASSES.

 >>> class Foo(object):
...     pass

>>> type(Foo)
type

 

В приведенном выше примере только BaseClass является object так что наш метаклассом будет тип object , который является type . Можно переопределить значение по умолчанию, однако это зависит от того, используем ли мы Python 2 или Python 3:

Специальный атрибут уровня класса __metaclass__ можно использовать для указания метакласса.

 class MyDummy(object):
    __metaclass__ = mytype
type(MyDummy)  # <class '__main__.mytype'>

 

Специальный metaclass ключевое слово аргумент указать метакласса.

 class MyDummy(metaclass=mytype):
    pass
type(MyDummy)  # <class '__main__.mytype'>

 

Любые ключевые аргументы (кроме metaclass ) в объявлении класса будут переданы метаклассом. Таким образом , class MyDummy(metaclass=mytype, x=2) будет проходить x=2 в качестве ключевого слова аргумента mytype конструктора.

Прочтите это описание в углубленную питона мета-классов для более подробной информации.