如何编写自己的元类?
How to write own metaclass?
如何在python中创建元类?我试着像教程中那样写:
class Meta(type):
def __new__(mcs, name, bases, attrs):
attrs2 = {'field2': 'Test'}
attrs2.update(attrs)
return super(Meta, mcs).__new__(mcs, name, bases, attrs2)
class Test(object):
__metaclass__ = Meta
field1 = 10
test = Test()
print(test.field1)
print(test.field2)
但是此代码失败并出现错误:
10
Traceback (most recent call last):
File "main.py", line 18, in <module>
print(test.field2)
AttributeError: 'Test' object has no attribute 'field2'
如何在 python 3.7+ 中正确声明元类?
已更新
我已经用实际错误更改了我的问题。
您查看的教程涵盖Python 2.
在 Python 3 中,语法更改之一就是为 class 声明元 class 的方式。
您无需更改 metaclass 代码,只需将 class 声明更改为:
class Test(metaclass=Meta):
field1 = 10
它会起作用。
所以,简而言之:对于 Python 3 中的元 class,您必须在 class 声明中传递相当于 "keyword argument" 的内容,其中姓名 "metaclass"。 (另外,在Python 3中,不需要显式继承自object)
在 Python 2 中,这是通过在 class 的 body 中存在特殊变量 __metaclass__
来实现的,如您的示例所示。 (此外,当设置元 class 时,从 'object' 继承是可选的,因为从类型派生的元 class 会为你做这件事。
新语法的主要优点之一是它允许元class中的特殊方法__prepare__
可以return自定义命名空间object在构建 class body 本身时使用。它很少使用,今天很难提出一个真正的 "serious" 用例。对于玩具和玩耍来说,这很棒,允许 "magic autonamed enumerations" 和其他东西 - 但在设计 Python 3 时,他们认为这是允许 OrderedDict
作为 class 命名空间,以便 metaclass' __new__
和 __init__
方法可以知道属性声明的顺序。从 Python 3.6 开始,class body 命名空间默认排序,不需要单独使用 __prepare__
方法。
如何在python中创建元类?我试着像教程中那样写:
class Meta(type):
def __new__(mcs, name, bases, attrs):
attrs2 = {'field2': 'Test'}
attrs2.update(attrs)
return super(Meta, mcs).__new__(mcs, name, bases, attrs2)
class Test(object):
__metaclass__ = Meta
field1 = 10
test = Test()
print(test.field1)
print(test.field2)
但是此代码失败并出现错误:
10
Traceback (most recent call last):
File "main.py", line 18, in <module>
print(test.field2)
AttributeError: 'Test' object has no attribute 'field2'
如何在 python 3.7+ 中正确声明元类?
已更新 我已经用实际错误更改了我的问题。
您查看的教程涵盖Python 2.
在 Python 3 中,语法更改之一就是为 class 声明元 class 的方式。 您无需更改 metaclass 代码,只需将 class 声明更改为:
class Test(metaclass=Meta):
field1 = 10
它会起作用。
所以,简而言之:对于 Python 3 中的元 class,您必须在 class 声明中传递相当于 "keyword argument" 的内容,其中姓名 "metaclass"。 (另外,在Python 3中,不需要显式继承自object)
在 Python 2 中,这是通过在 class 的 body 中存在特殊变量 __metaclass__
来实现的,如您的示例所示。 (此外,当设置元 class 时,从 'object' 继承是可选的,因为从类型派生的元 class 会为你做这件事。
新语法的主要优点之一是它允许元class中的特殊方法__prepare__
可以return自定义命名空间object在构建 class body 本身时使用。它很少使用,今天很难提出一个真正的 "serious" 用例。对于玩具和玩耍来说,这很棒,允许 "magic autonamed enumerations" 和其他东西 - 但在设计 Python 3 时,他们认为这是允许 OrderedDict
作为 class 命名空间,以便 metaclass' __new__
和 __init__
方法可以知道属性声明的顺序。从 Python 3.6 开始,class body 命名空间默认排序,不需要单独使用 __prepare__
方法。