Python defaultdict 对象的属性引发 AttributeError

Python defaultdict object's attribute raises AttributeError

我有 Python 2.7 代码,它使用 defaultdict 创建一个字典 mydict,它创建 MyClass 的默认对象,如下所示。

我的理解是,如果关键字 foo 在 defaultdict 中不存在,那么将创建一个 MyClass 的新对象,并且由于我有一个 __init__() 方法,那么属性 value 也会存在。那么为什么下面的代码不起作用,我有:

print mydict['foo'].value # Raises AttributeError

但是,此代码确实有效:

mydict['foo'].value = 1 # Works fine

解决错误的正确方法是什么? (顺便说一句,我是 C++/Java 程序员。)

下面是完整的代码:

from collections import defaultdict

class MyClass(object):
    def __init__(self):
        self.value = 0

mydict = defaultdict(lambda: MyClass)
print mydict['foo'].value # Raises AttributeError
#mydict['foo'].value += 1 # Raises AttributeError
#mydict['foo'].value = 1 # Works fine

结果:

AttributeError                            Traceback (most recent call last)
<ipython-input-16-c9dd776d73de> in <module>()
      6 
      7 mydict = defaultdict(lambda: MyClass)
----> 8 print mydict['foo'].value # Raises AttributeError
      9 #mydict['foo'].value += 1 # Raises AttributeError
     10 #mydict['foo'].value = 1 # Works fine

AttributeError: type object 'MyClass' has no attribute 'value'

当您指定 defaultdict(lambda: MyClass) 时,默认字典生成的是 MyClass 定义(通过 lambda),它没有 value,因为它没有在 class,因为这就是 return 使用该特定构造编辑的内容(如果它是可调用对象,则默认 dict 将调用构造它的第一个参数,您可以自己在异常中看到这一点您在问题中包含的消息)。看这个例子:

>>> MyClass.value
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'MyClass' has no attribute 'value'
>>> mydict['foo'].value = 1
>>> MyClass.value
1

如果您真的想要 return 原始 class,请像这样提供该值属性(但它将在所有默认值之间共享)

class MyClass(object):
    value = None

或者做你真正想要的,即提供 class 的默认实例,你可以在 lambda 中手动调用它,或者将其简化为:

mydict = defaultdict(MyClass)