外部类范围中找不到变量

时间:2013-10-24 07:49:42

标签: python class namespaces

我有这段代码:

class Attributes(object):
    class __metaclass__(type):
        def __init__(self, cls_name, cls_bases, cls_dict):
            # super(Attributes.__metaclass__, self) # NameError: global name 'Attributes' is not defined
            super(__metaclass__, self).__init__(
                cls_name, cls_bases, cls_dict)

给出

NameError: global name '__metaclass__' is not defined

为什么在外部范围内找不到__metaclass__变量?

3 个答案:

答案 0 :(得分:2)

试试这个

super(Attributes.__metaclass__, self).__init__(cls_name, cls_bases, cls_dict)

答案 1 :(得分:1)

创建类时,只能看到其名称。在完成创建类之前,它的内容尚不存在。因此,类中的部分在创建期间无法访问类的任何字段。因此,您需要使用完全限定名称来表示您要访问类

的字段

您目前正在创建课程SimpleModel,同时您正在创建课程Attributes,同时正在创建课程__metaclass__。由于当您执行此操作时,类SimpleModel尚未存在,方法__init__尚未成为现有任何内容的一部分。首先创建它,然后,它将成为类__metaclass__的一部分。因此,无法知道标识符__metaclass__。由于__metaclass__也永远不会成为全局,因此在调用时,无法识别此标识符。

这就是为什么此时你的范围内没有__metaclass__的原因,但是当稍后调用__init__时,只有SimpleModel可通过全局范围获得,所以你可以根据您的名字命名:SimpleModel.Attributes.__metaclass__

答案 2 :(得分:0)

看起来答案是这样的:

方法的外部范围不是类体,而是包含类的外部函数或模块。

这就是

的原因
class Test():
    attr_1 = 'smth'
    def a_method(self):
        attr_1  # not visible on this line
方法attr_1

中无法看到

Test.a_method

解决方案是在全球范围内定义元类:

class AttributesMeta(type):
    def __init__(self, cls_name, cls_bases, cls_dict):
        super(__metaclass__, self).__init__(
            cls_name, cls_bases, cls_dict)

class Attributes(object):
    __metaclass__ = AttributesMeta