Этот быстрый совет дает краткий обзор того, что мы подразумеваем под метаклассом в 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 
 | 
Атрибут __metaclass__
  Скажем, что мы создали класс 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 — это класс.  Если вы хотите углубиться в метаклассы, вы можете проверить этот учебник .