6

我一直在尝试学习 Python 中的元类。我明白了主要想法,但我似乎无法激活该机制。据我了解,您可以在构建类 K 时将 M 指定为元类,方法是__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
西班牙的雨
4

我不应该在 1 和 2 之后看到“西班牙的雨”吗?这里发生了什么?

4

3 回答 3

14

在 Python 3(您正在使用)中,元类由类定义中的关键字参数指定:

class ClassMeta(metaclass=M):
  pass

指定__metaclass__类属性或全局变量是 Python 2.x 中的旧语法,不再受支持。另请参阅“Python 3 中的新增功能”PEP 2115

于 2009-05-04T01:29:25.473 回答
2

这在 Python 2.6(及更早版本)中可以正常工作,但在 3.0 中元类的指定方式不同:

class ArgMeta(metaclass=M): ...
于 2009-05-04T01:33:34.730 回答
2

元类的语法在 Python 3.0中发生了变化。__metaclass__属性在类或模块级别不再是特殊的。要执行您想要执行的操作,您需要指定metaclassclass语句的关键字参数:

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

如你所料。

于 2009-05-04T01:37:32.753 回答