Python 字典类属性,它引用定义中的其他类属性

Python 字典类属性,它引用定义中的其他类属性,python,dictionary,class-attributes,Python,Dictionary,Class Attributes,虽然有很多方法可以解决这个问题,但由于人格缺陷,在我理解失败的本质之前,我不能放过它 尝试: class OurFavAnimals(object): FAVE = 'THATS ONE OF OUR FAVORITES' NOTFAVE = 'NAH WE DONT CARE FOR THAT ONE' UNKNOWN = 'WHAT?' FAVES = defaultdict(lambda: UNKNOWN, {x:FAVE for x in ['dog',

虽然有很多方法可以解决这个问题,但由于人格缺陷,在我理解失败的本质之前,我不能放过它

尝试:

class OurFavAnimals(object):
    FAVE = 'THATS ONE OF OUR FAVORITES'
    NOTFAVE = 'NAH WE DONT CARE FOR THAT ONE'
    UNKNOWN = 'WHAT?'
    FAVES = defaultdict(lambda: UNKNOWN, {x:FAVE for x in ['dog', 'cat']})
    FAVES['Crab'] = NOTFAVE 
在以下情况下失败:

      3     NOTFAVE = 'NAH WE DONT CARE FOR THAT ONE'
      4     UNKNOWN = 'WHAT?'
----> 5     FAVES = defaultdict(lambda: UNKNOWN, {x:FAVE for x in ['dog', 'cat']})
      6     FAVES['Crab'] = NOTFAVE

NameError: global name 'FAVE' is not defined

为什么??为什么它能找到
未知
,却找不到
FAVE
?是因为它在字典理解中吗?

是的,是因为它在字典理解中。请注意,它也不是“查找”
UNKNOWN
;它只是还没有找到它,因为
UNKNOWN
只在lambda中引用。如果您用其他内容替换dict理解以允许类定义成功,那么稍后如果您尝试访问不存在的键(因为它将尝试调用该lambda),您将得到一个错误。所以如果你把它改成

FAVES = defaultdict(lambda: UNKNOWN, {'a': 1})
您将获得:

>>> OurFavAnimals.FAVES['x']
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    OurFavAnimals.FAVES['x']
  File "<pyshell#2>", line 5, in <lambda>
    FAVES = defaultdict(lambda: UNKNOWN, {'a': 1})
NameError: global name 'UNKNOWN' is not defined

lambda和dictionary都创建嵌套在类作用域中的函数作用域,因此它们不能直接访问类变量。另请参见。

我要添加的内容,解决这一问题的最好方法是使用
self.FAVE=[…]
在类的
\uuuu init\uuuu()
方法中定义(部分或全部)这些变量。谢谢!但这仍然很奇怪;为什么会这样?我认为在Python中,嵌套作用域总是可以访问父作用域。至少,根据我的经验,以前一直是这样。@eriophora:类的作用域是不同的。关于这个问题的一些讨论,请参见我链接的问题。Sam的回答,虽然这里不是这样,很难想象有一个场景是这样的,假设你必须用相同的参数初始化这个类的几十万个实例。我有一个详细的背景故事来证明这一点(“假设你想模拟一大群通灵者,他们可以即时相互交流,周游世界,学习新动物的名字,并任意将它们分配到他们共同的“最喜欢”或“不喜欢”的动物列表中……”)@布伦巴恩,你链接的答案是难以置信的;我很尴尬,我没早点找到它。也许人们应该在堆栈溢出上获得分数,因为他们用问题的交替措辞标记已解决的问题。或者也许我应该在搜索词中加入“列表理解”。。。
class Foo(object):
    something = "Hello"
    def meth(self):
        print(something)