3

我有这个代码:

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__在外部范围内找不到变量?

4

3 回答 3

2

试试这个

super(Attributes.__metaclass__, self).__init__(cls_name, cls_bases, cls_dict)
于 2013-10-24T08:19:28.977 回答
1

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

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

这就是为什么__metaclass__此时您的范围内没有 no 的原因,但是当稍后__init__被调用时,只有 aSimpleModel可通过全局范围使用,因此您可以将您的名字基于它: SimpleModel.Attributes.__metaclass__.

于 2013-10-24T09:27:43.730 回答
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
于 2013-10-24T08:47:06.740 回答