Подтвердить что ты не робот

Python hasattr в списке значений словарей всегда возвращает false?

У меня есть словарь, который иногда получает вызовы для несуществующих ключей, поэтому я пытаюсь использовать 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 использует пустой getattr по умолчанию во второй раз, теряя значение 1 в этом процессе! Почему это?

4b9b3361

Ответ 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 = {}

Ответ 2

Клавиша слова не совпадает с атрибутом объекта

thing1 = {'a', 123}
hasattr(thing1, 'a') # False
class c: pass
thing2 = c()
thing2.a = 123
hasattr(thing2, 'a') # True

Ответ 3

Похоже, все, что вам нужно, это одна строка:

def add_to_info(self, key_string, integer):
    self.info.setdefault(key_string, []).append(integer)

Ответ 4

Для проверки элементов в списке/словаря, использовать 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)

Ответ 5

Это удобно для определения отражающего 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 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