我一直在努力学习Python中的元类。我得到了主要的想法,但我似乎无法激活机制。据我了解,通过在全局或类级别将__metaclass__
设置为M,可以在构造类K时将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之后看到“西班牙的雨”吗?这是怎么回事?
答案 0 :(得分:13)
在Python 3(您正在使用)中,元类由类定义中的关键字参数指定:
class ClassMeta(metaclass=M):
pass
指定__metaclass__
类属性或全局变量是Python 2.x中的旧语法,不再受支持。另请参阅"What's new in Python 3"和PEP 2115。
答案 1 :(得分:2)
这在Python 2.6(及更早版本)中可以正常工作,但在3.0中,元类的指定方式不同:
class ArgMeta(metaclass=M): ...
答案 2 :(得分:2)
元类的语法在Python 3.0中有changed。 __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
正如您所期望的那样。