2017-12-13 14 views
0

defaultdictを使用して、デフォルトオブジェクトMyClassを作成する辞書mydictを作成するPython 2.7のコードを以下に示します。Pythonのdefaultdictオブジェクトの属性がAttributeErrorを発生します

私の理解では、キー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' 

答えて

3

あなたがdefaultdict(lambda: MyClass)を指定して、どのようなデフォルトのdictは、valueがクラスに定義されていないので、その特定の構造体で返されているものと同じように(ラムダを通して)MyClassの定義が生成されます(デフォルトのdictは、呼び出し可能なオブジェクトであればそれが作成され、あなたはあなたがあなたの質問に含まれている例外メッセージに既に自分自身を見ることができます)。あなたは本当に、生のクラスを返すようなので(しかし、それはすべてのデフォルト値間で共有されます)、その値属性

class MyClass(object): 
    value = None 

を提供したり、本当に何をしたい場合は

>>> 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 

:この例を参照してください。あなたはラムダでそれを手動で呼び出すことができるクラスのデフォルトのインスタンスを提供するか、単純にそれを減らすことができます:

mydict = defaultdict(MyClass) 
+0

ありがとう。 'defaultdict(lambda:MyClass)'と 'defaultdict(MyClass)'の2つの宣言の違いは何ですか? – stackoverflowuser2010

+0

'lambda:MyClass'は、基本的に、' MyClass'を返す引数を取らない関数です。これは文字通り 'MyClass'クラス定義を返します。 – metatoaster

+0

'defaultdict(lambda:MyClass)'を使用すると 'mydict ['foo']。value = 1'という文がなぜ機能するのか説明できますか?あなたの議論によると、 'lambda'を使うとメンバー変数' value'は存在してはいけません。 – stackoverflowuser2010

関連する問題