我有这个代码:
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