Python对字典列表值的hasattr总是返回false?

时间:2012-05-23 17:13:56

标签: python list class dictionary hasattr

我有一本字典,有时会收到对不存在的密钥的调用,所以我尝试使用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的值进行中!这是为什么?

6 个答案:

答案 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'