python:元类中__new__的时间

时间:2010-09-16 05:40:44

标签: python namespaces metaclass

以下代码无法编译;它说

  

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而工作正常。

我想知道为什么我无法使用fieldssuper().fields

1 个答案:

答案 0 :(得分:4)

fields['key'] = 'value'在元类机器启动之前运行。

class foo(object):
    var1 = 'bar'

    def foobar(self):
        pass

当python命中class语句时,它会进入一个新的本地命名空间。

  1. 它评估var1 = 'bar'语句。这相当于locals()['var1'] = 'bar'

  2. 然后评估def foobar语句。这相当于locals()['var'] = the result of compiling the function

  3. 然后locals()以及类名,继承的类和元类传递给元类__new__方法。在示例中,元类只是type

  4. 然后退出新的本地命名空间,并将__new__返回的类对象粘贴到外部命名空间中,名称为foo

  5. 您使用A.fields时代码有效,因为已经创建了类A,因此Meta安装了fields A执行了上述过程1}}。

    您不能使用super().fields,因为类名B未定义为在超级运行时传递给super。那就是你需要它super(B).fields,但{<1}}在类创建之后被定义为

    更新

    根据您对该问题的评论的回复,以下是一些代码可以执行您想要的操作。

    B