以下代码无法编译;它说
NameError:名称'fields'不是 定义
在最后一行。是因为__new__
在达到fields
作业之后才被调用?我该怎么办?
class Meta(type):
def __new__(mcs, name, bases, attr):
attr['fields'] = {}
return type.__new__(mcs, name, bases, attr)
class A(metaclass = Meta):
def __init__(self, name):
pass
class B(A):
fields['key'] = 'value'
修改
我发现这不是时间问题;这是名字隐藏的问题。如果我写A.fields
而工作正常。
我想知道为什么我无法使用fields
或super().fields
。
答案 0 :(得分:4)
fields['key'] = 'value'
在元类机器启动之前运行。
class foo(object):
var1 = 'bar'
def foobar(self):
pass
当python命中class
语句时,它会进入一个新的本地命名空间。
它评估var1 = 'bar'
语句。这相当于locals()['var1'] = 'bar'
然后评估def foobar
语句。这相当于locals()['var'] = the result of compiling the function
然后将locals()
以及类名,继承的类和元类传递给元类__new__
方法。在示例中,元类只是type
。
然后退出新的本地命名空间,并将__new__
返回的类对象粘贴到外部命名空间中,名称为foo
。
您使用A.fields
时代码有效,因为已经创建了类A
,因此Meta
安装了fields
A
执行了上述过程1}}。
您不能使用super().fields
,因为类名B
未定义为在超级运行时传递给super。那就是你需要它super(B).fields
,但{<1}}在类创建之后被定义为。
根据您对该问题的评论的回复,以下是一些代码可以执行您想要的操作。
B