36

存在しないキーの呼び出しを時々受け取る辞書があるので、これらのケースを処理するためにhasattrandを使用します。getattr

key_string = 'foo'
print "current info:", info
print hasattr(info, key_string)
print getattr(info, key_string, [])
if hasattr(info, key_string):
    array = getattr(info, key_string, [])
array.append(integer)
info[key_string] = array
print "current info:", info

これを初めて実行するときinteger = 1:

current info: {}
False
[]
current info: {'foo': [1]}

このコードを次のように再度実行しますinteger = 2

instance.add_to_info("foo", 2)

current info: {'foo': [1]}
False
[]
current info: {'foo': [2]}

最初の実行は明らかに成功しています{'foo': [1]}が ( )、hasattrfalse を返しgetattr、2 回目はデフォルトの空の配列を使用するため1、その過程で の値が失われます! どうしてこれなの?

4

5 に答える 5

53

hasattrディクショナリのメンバーをテストしません。in代わりに演算子を使用するか、次のメソッドを使用し.has_keyます。

>>> example = dict(foo='bar')
>>> 'foo' in example
True
>>> example.has_key('foo')
True
>>> 'baz' in example
False

ただし、dict.has_key()非推奨であり、PEP 8 スタイルガイドで推奨されておらず、Python 3 で完全に削除されていることに注意してください。

ちなみに、変更可能なクラス変数を使用すると、次のような問題が発生します。

>>> class example(object):
...     foo = dict()
...
>>> A = example()
>>> B = example()
>>> A.foo['bar'] = 'baz'
>>> B.foo
{'bar': 'baz'}

代わりにそれを初期化します__init__

class State(object):
    info = None

    def __init__(self):
        self.info = {}
于 2012-05-23T17:19:55.560 に答える
9

辞書キーはオブジェクト属性と同じではありません

thing1 = {'a', 123}
hasattr(thing1, 'a') # False
class c: pass
thing2 = c()
thing2.a = 123
hasattr(thing2, 'a') # True
于 2012-05-23T17:18:23.343 に答える
2

リスト/辞書の要素をテストするには、 を使用しますin。デフォルトを使用するには、次を使用できますdict.get

def add_to_info(self, key_string, integer):
    array = self.info.get(key_string, [])
    array.append(integer)
    self.info[key_string] = array

または、defaultdict を使用します。

from collections import defaultdict
class State(object):
    info = defaultdict(list)

    def add_to_info(self, key_string, integer):
        self.info[key_string].append(integer)
于 2012-05-23T17:21:41.087 に答える
1

必要なのは1行だけのようです。

def add_to_info(self, key_string, integer):
    self.info.setdefault(key_string, []).append(integer)
于 2012-05-23T17:24:40.587 に答える