存在しないキーの呼び出しを受け取ることがある辞書があるので、hasattr
と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]}
)、hasattr
はfalseを返し、getattr
はデフォルトの空の配列を2回目に使用し、1
の値を失いますプロセス!どうしてこれなの?
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 = {}
_
辞書キーはオブジェクト属性と同じではありません
thing1 = {'a', 123}
hasattr(thing1, 'a') # False
class c: pass
thing2 = c()
thing2.a = 123
hasattr(thing2, 'a') # True
リスト/辞書の要素をテストするには、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)
必要なのは1行だけのようです。
def add_to_info(self, key_string, integer):
self.info.setdefault(key_string, []).append(integer)