Статьи

Совет: что такое метакласс в Python?

Этот быстрый совет дает краткий обзор того, что мы подразумеваем под метаклассом в Python, и показывает некоторые примеры концепции.

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

Если вы использовали язык программирования, отличный от Python, концепция, которую вы поняли о классах, скорее всего, это способ создания новых объектов. Это также верно в Python, но Python делает еще один шаг вперед — классы также считаются объектами!

Итак, если вы создали следующий класс в Python:

1
2
class myClass(object):
   pass

Это просто означает, что объект с именем myClass был создан в памяти. Поскольку этот объект может создавать новые объекты, он считается классом . Это означает, что мы можем применять объектные операции к классам в Python, поскольку классы сами являются объектами.

Таким образом, мы можем выполнять операции над классами, такие как присвоение класса переменной, следующим образом:

1
2
class_object = myClass()
print class_object

Который возвращает:

1
<__main__.myClass object at 0x102623610>

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

1
2
3
4
def class_object(object):
    print object
     
class_object(myClass)

Который возвращает следующий вывод:

1
<class ‘__main__.myClass’>

В дополнение к другим операциям вы обычно можете наносить на объекты.

Может быть, вы сталкивались с ключевым словом type в Python? Скорее всего, вы использовали его для проверки типа какого-либо объекта, как показано в следующих примерах:

1
2
3
4
print type(‘abder’)
print type(100)
print type(100.0)
print type(int)

В этом случае вы получите следующий вывод:

1
2
3
4
<type ‘str’>
<type ‘int’>
<type ‘float’>
<type ‘type’>

Глядя на вывод, все кажется довольно ясным, пока вы не придете к типу type . Чтобы увидеть, что это может означать, давайте вернемся к нашему классу, который мы определили в начале этой статьи:

1
2
class myClass(object):
   pass

Теперь сделайте следующее:

1
print type(myClass)

Каков будет результат этого заявления? Это будет на удивление:

1
<type ‘type’>

Итак, мы можем заключить, что тип классов в Python — это type !

Какова связь между type и metaclass ? Ну, type — это metaclass , при условии, что metaclass по умолчанию — это type . Я знаю, что это может сбивать с толку, особенно тот type может использоваться для возврата класса некоторого объекта, как показано выше, но это связано с обратной совместимостью в Python. Итак, если вы напишите:

1
print type(type)

Ты получишь:

1
<type ‘type’>

Это означает, что type есть type !

Термин metaclass просто означает то, что используется для создания классов . Другими словами, это класс класса, что означает, что экземпляр класса в этом случае является классом. Таким образом, type считается metaclass так как экземпляр type является классом.

Например, когда мы упомянули следующее утверждение выше:

1
class_object = myClass()

Это просто создает объект / экземпляр класса myClass . Другими словами, мы использовали класс для создания объекта.

Точно так же, когда мы сделали следующее:

1
2
class myClass(object):
   pass

metaclass был использован для создания класса myClass (который считается type ). Таким образом, как и объект, являющийся экземпляром класса, класс является экземпляром metaclass .

В этом разделе мы увидим, как мы можем использовать metaclass для создания класса, а не использовать оператор class как мы видели в учебнике по классам и объектам . Как мы видели выше, metaclass по умолчанию — это type . Таким образом, мы можем использовать следующую инструкцию для создания нового класса:

1
new_class = type(‘myClass’,(),{})

Если вы хотите упростить ситуацию, вы можете присвоить имя переменной тому же имени myClass .

Словарь { } здесь используется для определения атрибутов класса. Итак, имея следующее утверждение:

1
myClass = type(‘myClass’,(),{‘a’:True})

Похоже на:

1
2
class myClass(object):
   a = True

Скажем, что мы создали класс myClass следующим образом:

1
2
3
class myClass(object):
   __metaclass__ = myMetaClass
   pass

В этом случае создание класса будет происходить с использованием myMetaClass вместо type , как myMetaClass ниже:

1
myClass = myMetaClass(className, bases, dictionary)

Если вы хотите иметь контроль над тем, как вы создаете и инициализируете класс после его создания, вы можете просто использовать метакласс __new__ метод и __init__ конструктор, соответственно. Итак, когда вышеупомянутый myMetaClass вызывается, это то, что будет происходить за кулисами:

1
2
myClass = myMetaClass.__new__(myMetaClass, name, bases, dictionary)
myMetaClass.__init__(myClass, name, bases, dictionary)

Я не хочу, чтобы этот краткий совет был длиннее, но, резюмируя, мы можем заключить, что metaclass используется в Python для создания класса. То есть экземпляр metaclass — это класс. Если вы хотите углубиться в метаклассы, вы можете проверить этот учебник .