example - hasattr python
El hasattr de Python en la lista de valores de los diccionarios siempre devuelve falso? (5)
Tengo un diccionario que a veces recibe llamadas para claves no existentes, así que trato de usar hasattr
y getattr
para manejar estos casos:
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
La primera vez que esto se ejecuta con integer = 1
:
current info: {}
False
[]
current info: {''foo'': [1]}
Ejecutando este código de nuevo con integer = 2
:
instance.add_to_info("foo", 2)
current info: {''foo'': [1]}
False
[]
current info: {''foo'': [2]}
La primera ejecución es claramente exitosa ( {''foo'': [1]}
), pero hasattr
devuelve false y getattr
usa la matriz en blanco predeterminada la segunda vez, perdiendo el valor de 1
en el proceso. ¿Por qué es esto?
Es útil haber definido un getAttr
reflexivo que obtiene atributos o claves de un objeto.
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
Para probar los elementos en una lista / diccionario, use in
. Para usar los valores predeterminados, puedes usar dict.get
:
def add_to_info(self, key_string, integer):
array = self.info.get(key_string, [])
array.append(integer)
self.info[key_string] = array
O use 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)
Parece que todo lo que necesitas es una línea:
def add_to_info(self, key_string, integer):
self.info.setdefault(key_string, []).append(integer)
Una clave de diccionario no es lo mismo que un atributo de objeto
thing1 = {''a'', 123}
hasattr(thing1, ''a'') # False
class c: pass
thing2 = c()
thing2.a = 123
hasattr(thing2, ''a'') # True
hasattr
no prueba para miembros de un diccionario. Utilice el operador in
lugar, o el método .has_key
:
>>> example = dict(foo=''bar'')
>>> ''foo'' in example
True
>>> example.has_key(''foo'')
True
>>> ''baz'' in example
False
Pero tenga en cuenta que dict.has_key()
ha quedado en desuso, se recomienda en su contra por la guía de estilo PEP 8 y se ha eliminado por completo en Python 3.
Por cierto, se encontrará con problemas al utilizar una variable de clase mutable:
>>> class example(object):
... foo = dict()
...
>>> A = example()
>>> B = example()
>>> A.foo[''bar''] = ''baz''
>>> B.foo
{''bar'': ''baz''}
__init__
en tu __init__
en su lugar:
class State(object):
info = None
def __init__(self):
self.info = {}