36

我有一本字典,有时会收到对不存在键的调用,所以我尝试使用hasattrgetattr处理这些情况:

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在过程中丢失了 的值!为什么是这样?

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

或使用默认字典:

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

看起来你只需要一行:

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

您可以在 dict 类型对象上使用 .get() 方法。如果未定义,此方法不会引发关键错误。此外,作为对象的 getattr(),您可以在其上指定默认值。

>> {'name': 'Me'}.get('name1', 'StackOverflow')
>> 'StackOverflow'
于 2020-04-01T19:24:32.563 回答