Разве __metaclass__ не должен принудительно использовать метакласс в Python?
-
03-07-2019 - |
Вопрос
Я пытался узнать о метаклассах в Python.Я понял основную идею, но не могу активировать механизм.Насколько я понимаю, вы можете указать M в качестве метакласса при создании класса K, установив __metaclass__
к M на глобальном уровне или уровне класса.Чтобы проверить это, я написал следующую программу:
p = print
class M(type):
def __init__(*args):
type.__init__(*args)
print("The rain in Spain")
p(1)
class ClassMeta:
__metaclass__ = M
p(2)
__metaclass__ = M
class GlobalMeta: pass
p(3)
M('NotMeta2', (), {})
p(4)
Однако, когда я запускаю его, я получаю следующий вывод:
C:\Documents and Settings\Daniel Wong\Desktop>python --version Python 3.0.1 C:\Documents and Settings\Daniel Wong\Desktop>python meta.py 1 2 3 The rain in Spain 4
Разве мне не стоит посмотреть «Дождь в Испании» после 1 и 2?Что тут происходит?
Решение
В Python 3 (который вы используете) метаклассы указываются ключевым параметром в определении класса:
class ClassMeta(metaclass=M):
pass
Задание свойства класса или глобальной переменной класса __ metaclass __
является старым синтаксисом из Python 2.x и более не поддерживается. См. Также " Что нового в Python 3 " и < a href = "http://www.python.org/dev/peps/pep-3115/" rel = "nofollow noreferrer"> PEP 2115 .
Другие советы
Это работает так, как вы ожидаете в Python 2.6 (и более ранних версиях), но в 3.0 метаклассы определены по-другому:
class ArgMeta(metaclass=M): ...
Синтаксис метаклассов имеет измененный в Python 3.0.А __metaclass__
Атрибут больше не является особенным ни на уровне класса, ни на уровне модуля.Чтобы сделать то, что вы пытаетесь сделать, вам нужно указать metaclass
в качестве аргумента ключевого слова для class
заявление:
p = print
class M(type):
def __init__(*args):
type.__init__(*args)
print("The rain in Spain")
p(1)
class ClassMeta(metaclass=M): pass
Выход:
1
The rain in Spain
Как и следовало ожидать.