example python list class dictionary hasattr

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 = {}