Python - 在类体内引用类名

3 投票
2 回答
1618 浏览
提问于 2025-04-16 01:43

在Python中,我想要一个类属性,也就是一个字典,并且希望它有一些初始化的值。我写了这段代码:

class MetaDataElement:
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
    mapInitiator2Type = {'!':MetaDataElement.MD_CATEGORY, 
                         '#':MetaDataElement.MD_TAG}

但是当我尝试运行这段代码时,出现了一个错误信息,提示“NameError: name 'MetaDataElement' is not defined”。你能帮我吗?

提前谢谢你。

2 个回答

1

首先,你现在用的是旧式类。你应该使用新式类,像这样:

class MetaDataElement(object):
    ...

注意这里的 (object)。不过,不管怎样,当你提到类的属性时,简单地去掉 MetaDataElement.。这样做之后,它看起来会是这样的:

class MetaDataElement(object):
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
    mapInitiator2Type = {'!': MD_CATEGORY, 
                         '#': MD_TAG}
3

在构建MetaDataElement的时候,你不能引用它,因为那时候它还不存在。因此,

class MetaDataElement:
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
    mapInitiator2Type = {'!':MetaDataElement.MD_CATEGORY, 
                         '#':MetaDataElement.MD_TAG}

这个代码会失败,因为构建mapInitiator2Type的时候需要MetaDataElement有一些属性,但它那时候还没有。你可以把你的常量MD_INVALID等看作是只在你这个类构建过程中使用的变量。这就是为什么下面的代码可以工作的原因,正如icktoofay所说:

class MetaDataElement:
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
    mapInitiator2Type = {'!': MD_CATEGORY,  # MD_CATEGORY is like a local variable!
                         '#': MD_TAG}

不过,在任何还没有被解释的代码中,你可以引用MetaDataElement,就像下面这样:

    def method_of_MetaDataElement(self):
        print MetaDataElement.MD_TAG

在这里你甚至必须引用MetaDataElement,因为在执行method_of_MetaDataElement()时,MD_TAG并不是一种局部变量(MD_TAG只是在类构建时被定义为局部变量)。一旦MetaDataElement这个类被创建,MD_TAG就变成了一个类的属性,这就是为什么method_of_MetaDataElement()必须这样引用它的原因。

撰写回答