Метаклассы

Введение

Примеры

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

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

  • 8

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

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

     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
    
    
     
  • 2

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

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

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

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

     import six
    
    class MyClass(six.with_metaclass(SomeMetaclass)):
        pass 
  • 0

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

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

     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] 
  • 2

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

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

    В 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) 
  • 0

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

    Возможно, вы слышали, что все в 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 довольно «взломан», и концепция метакласса важна, если вы делаете продвинутые вещи, такие как метапрограммирование, или если вы хотите контролировать, как инициализируются ваши классы.

Синтаксис

Параметры

Примечания