在外部类作用域中找不到变量



我有这个代码:

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__变量?

试试这个

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

创建类时,只有其名称可见。 在完成类创建之前,其内容尚不存在。 因此,类中的部件在创建过程中无法访问类的任何字段。 因此,您将需要使用完全限定的名称来表示您想要访问类的字段

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

这就是为什么

此时您的作用域中没有__metaclass__的原因,但是当稍后调用__init__时,只有SimpleModel可以通过全局作用域使用,因此您可以基于它命名:SimpleModel.Attributes.__metaclass__

看起来答案是这样的:

方法的外部作用域不是类主体,而是包含类或模块的外部函数。

这就是为什么在

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

最新更新