我有一本字典,有时会收到对不存在的密钥的调用,所以我尝试使用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
第二次使用默认空白数组,失去1
的值进行中!这是为什么?
答案 0 :(得分:33)
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 = {}
答案 1 :(得分:4)
字典键与对象属性
不同thing1 = {'a', 123}
hasattr(thing1, 'a') # False
class c: pass
thing2 = c()
thing2.a = 123
hasattr(thing2, 'a') # True
答案 2 :(得分: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)
答案 3 :(得分:1)
看起来你需要的只是一行:
def add_to_info(self, key_string, integer):
self.info.setdefault(key_string, []).append(integer)
答案 4 :(得分:-1)
定义一个从对象获取属性或键的反射getAttr
非常方便。
def getAttr(obj, attribute, default=''):
# like getattr, but also check the keys of obj, and can return a default, if no key or no attribute was found.
# note there's a priority to attribute if both attribute and key exist.
result = getattr(obj, attribute) if hasattr(obj, attribute) else None
if result is None:
result = obj.get(attribute, default) if isinstance(obj, dict) else default
return result
答案 5 :(得分:-1)
您可以在dict类型对象上使用.get()方法。如果未定义,则此方法不会引发键错误。另外,作为对象的getattr(),您可以在其上指定一个默认值。
>> {'name': 'Me'}.get('name1', 'StackOverflow')
>> 'StackOverflow'