Документация по Python

Метаклассы

В: Документация по Python

Введение

Примеры

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

Когда 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 конструктора.

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

Синглтоны с использованием метаклассов

Синглтон - это шаблон, который ограничивает создание экземпляра класса одним экземпляром / объектом. Для получения дополнительной информации о питоных одноэлементных шаблонах проектирования, см здесь .

 class SingletonType(type):
    def __call__(cls, *args, **kwargs):
        try:
            return cls.__instance
        except AttributeError:
            cls.__instance = super(SingletonType, cls).__call__(*args, **kwargs)
            return cls.__instance

 

Класс MySingleton (объект): __metaclass__ = SingletonType  класс MySingleton (metaclass = SingletonType): проход

 MySingleton() is MySingleton()  # True, only one instantiation occurs


 

Использование метакласса

Синтаксис метакласса

класс MyClass (объект): __metaclass__ = SomeMetaclass  класс MyClass (metaclass = SomeMetaclass): проход

Python 2 и 3 Совместимость с six

 import six

class MyClass(six.with_metaclass(SomeMetaclass)):
    pass 

Пользовательский функционал с метаклассами

Функциональность в метаклассах может быть изменена таким образом , что всякий раз , когда строятся класс, строка печатается на стандартный вывод, или исключение. Этот метакласс напечатает имя создаваемого класса.

 class VerboseMetaclass(type):

    def __new__(cls, class_name, class_parents, class_dict):
        print("Creating class ", class_name)
        new_class = super().__new__(cls, class_name, class_parents, class_dict)
        return new_class


 

Вы можете использовать метакласс следующим образом:

 class Spam(metaclass=VerboseMetaclass):
    def eggs(self):
        print("[insert example string here]")
s = Spam()
s.eggs()


 

Стандартный вывод будет:

 Creating class Spam
[insert example string here] 

Введение в метаклассы

Что такое метакласс?

В Python все является объектом: целые числа, строки, списки, даже функции и сами классы являются объектами. И каждый объект является экземпляром класса.

Для того, чтобы проверить класс объекта х, можно назвать type(x) , так что :

 >>> type(5)
<type 'int'>
>>> type(str)
<type 'type'>
>>> type([1, 2, 3])
<type 'list'>

>>> class C(object):
...     pass
...
>>> type(C)
<type 'type'>    

 

Большинство классов в Python являются экземплярами type . type сам по себе также является класс. Такие классы, экземплярами которых также являются классы, называются метаклассами.

Самый простой метакласс

ОК, так что уже один метаклассом в Python: type . Можем ли мы создать еще один?

 class SimplestMetaclass(type):
    pass

class MyClass(object):
    __metaclass__ = SimplestMetaclass

 

Это не добавляет никакой функциональности, но это новый метакласс, обратите внимание, что MyClass теперь является экземпляром SimplestMetaclass:

 >>> type(MyClass)
<class '__main__.SimplestMetaclass'>

 

Метакласс, который делает что-то

Метакласс , который делает что - то , как правило , имеет приоритет type «S __new__ , чтобы изменить некоторые свойства создаваемого класса, перед вызовом оригинального __new__ , который создает класс:

 class AnotherMetaclass(type):
    def __new__(cls, name, parents, dct):
        # cls is this class
        # name is the name of the class to be created
        # parents is the list of the class's parent classes
        # dct is the list of class's attributes (methods, static variables)

        # here all of the attributes can be modified before creating the class, e.g.

        dct['x'] = 8  # now the class will have a static variable x = 8

        # return value is the new class. super will take care of that
        return super(AnotherMetaclass, cls).__new__(cls, name, parents, dct) 

Метакласс по умолчанию

Возможно, вы слышали, что все в Python является объектом. Это правда, и все объекты имеют класс:

 >>> type(1)
int

 

Буквальное 1 является экземпляром int . Давайте объявим класс:

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

 

Теперь давайте создадим его экземпляр:

 >>> bar = Foo()

 

Что такое класс bar ?

 >>> type(bar)
Foo

 

Хороший, bar является экземпляром Foo . Но что класс Foo сам?

 >>> type(Foo)
type

 

Хорошо, Foo сам является экземпляром type . Как насчет type сам?

 >>> type(type)
type

 

Так что же такое метакласс? А пока давайте представим, что это просто причудливое имя для класса класса. Takeaways:

  • В Python все является объектом, поэтому у всего есть класс
  • Класс класса называется метаклассом.
  • По умолчанию метакласса является type , и на сегодняшний день он является наиболее распространенным метаклассом

Но почему вы должны знать о метаклассах? Ну, сам Python довольно «взломан», и концепция метакласса важна, если вы делаете продвинутые вещи, такие как метапрограммирование, или если вы хотите контролировать, как инициализируются ваши классы.

Синтаксис

Параметры

Примечания

Еще от кодкамп
Замечательно! Вы успешно подписались.
Добро пожаловать обратно! Вы успешно вошли
Вы успешно подписались на кодкамп.
Срок действия вашей ссылки истек.
Ура! Проверьте свою электронную почту на наличие волшебной ссылки для входа.
Успех! Ваша платежная информация обновлена.
Ваша платежная информация не была обновлена.