lucas gabriel sánchez
¿Cómo compruebo si un objeto tiene algún atributo? Por ejemplo:
>>> a = SomeClass()
>>> a.property
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute 'property'
¿Cómo puedo saber si a
tiene el atributo property
antes de usarlo?
Jarret Hardie
Probar hasattr()
:
if hasattr(a, 'property'):
a.property
¡Vea la respuesta de zweiterlinde a continuación, quien ofrece buenos consejos sobre cómo pedir perdón! ¡Un enfoque muy pitónico!
La práctica general en python es que, si es probable que la propiedad esté allí la mayor parte del tiempo, simplemente llámela y deje que la excepción se propague o atrape con un bloque try/except. Esto probablemente será más rápido que hasattr
. Si es probable que la propiedad no esté allí la mayor parte del tiempo, o si no está seguro, utilice hasattr
probablemente será más rápido que caer repetidamente en un bloque de excepción.
-
Parece estar funcionando para verificar funciones en el espacio de nombres también, por ejemplo:
import string hasattr(string, "lower")
– riviera
8 de abril de 2011 a las 12:54
-
hasattr
es exactamente lo mismo que usartry
/except AttributeError
: la cadena de documentación de hasattr (en Python 2.7) dice que usa excepciones de captura manual de getattr.–Jeff Tratner
27 de abril de 2012 a las 3:04
-
@JeffTratner:
hasattr
desafortunadamente no es exactamente lo mismo que untry: ... except AttributeError:
en Python 2.x desdehasattr
voluntad atrapar todas las excepciones. Consulte mi respuesta para ver un ejemplo y una solución sencilla.– Martín Geisler
24 de abril de 2013 a las 7:44
-
hasattr no funciona si su objeto es un ‘dict’. Use el método in operator o haskey en esos casos.
– Anand Shiva
4 de abril de 2021 a las 12:13
-
se puede hacer por atributo para
self
? me gustaif not hasattr(self, 'property')
dentro de__init__()
de la creación del objeto– alper
14 de septiembre de 2021 a las 3:51
zweiterlinde
Como respondió Jarret Hardie, hasattr
hará el truco. Sin embargo, me gustaría agregar que muchos en la comunidad de Python recomiendan una estrategia de “más fácil pedir perdón que permiso” (EAFP) en lugar de “mirar antes de saltar” (LBYL). Vea estas referencias:
EAFP vs LBYL (Fue Re: Un poco decepcionado hasta ahora)
EAFP vs. LBYL @Code Like a Pythonista: Python idiomático
es decir:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
… es preferible a:
if hasattr(a, 'property'):
doStuff(a.property)
else:
otherStuff()
-
Pero, ¿cómo se comprueba que fue la propiedad a la que causó AttributeError y no algo en doStuff()? Parece que no. Creo que es realmente más fácil pedir perdón, pero muchas veces también es incorrecto.
– jpalecek
14 de abril de 2009 a las 13:22
-
EAFP parece… una locura. HasAttr telegrafía a los futuros programadores de mantenimiento que está comprobando un atributo en particular. Obtener una excepción no les dice nada a los futuros programadores y podría llevar a alguien a la madriguera del conejo.
–Ethan Heilman
14/10/2010 a las 18:54
-
@e5: tienes razón en este caso, pero en muchos casos EAFP es la única opción correcta. Por ejemplo, si verifica la existencia de un archivo y luego lo abre, esperando que definitivamente existirá, su código es incorrecto: el archivo puede ser eliminado o renombrado entre la verificación y el uso. Esto se denomina error TOCTOU (Tiempo de verificación hasta el momento de uso) y, además de causar fallas, también puede ser una fuente de vulnerabilidades de seguridad.
– Máx.
1 de junio de 2011 a las 13:08
-
@EthanHeilman solo es una locura cuando hay ambigüedad en el origen de la excepción, lo que se puede evitar con un buen diseño en la mayoría de los casos. La estructuración de la lógica en capas dentro de try/except/finally generalmente hace que la lógica sea más robusta (menos propensa a errores del programador) que ensuciar el código con verificaciones if preventivas para cada pieza de código consumidor. También hace que los errores sean muy explícitos y permite a los programadores consumidores la opción de tratar con ellos directamente.
– Pedro M. Elías
2 de enero de 2013 a las 16:23
-
La mayoría de las quejas de ambigüedad aquí se deben simplemente a que el código de muestra está mal estructurado. Lo único dentro de la
try:
debe ser el intento de acceso al atributo; no hay razón para envolver la ejecución dedoStuff
también. Sin embargo, todavía existe cierto potencial de ambigüedad: siproperty
es una propiedad calculada en lugar de un atributo simple, su implementación podría generarAttributeError
internamente. Es por eso que en casi todas las situaciones reales como esta,getattr
es preferible a cualquierahasattr
o atraparAttributeError
.–Carl Meyer
24/09/2013 a las 20:21
carl meyer
Puedes usar hasattr()
o atrapar AttributeError
pero si realmente solo desea el valor del atributo con un valor predeterminado si no está allí, la mejor opción es usar getattr()
:
getattr(a, 'property', 'default value')
-
Esto resuelve los dos problemas antes mencionados: a) La ambigüedad de la fuente de un posible AttributeError, b) Preservar el enfoque EAFP.
– Pedro M. Elías
2 de enero de 2013 a las 16:17
-
También es el 25% de las líneas de código. Seguramente esta tiene que ser la mejor solución.
– fatuhoku
24 de septiembre de 2013 a las 11:36
-
Esta es la mejor solución “si realmente solo desea el valor del atributo con un valor predeterminado”. Aunque creo que esto es lo que muchas personas realmente quieren cuando dicen que quieren detectar si un atributo está presente, el OP en realidad solicitó lo último, por lo que es razonable que las respuestas directas a esa pregunta (hasattr, AttributeError) aparezcan más arriba. .
–Carl Meyer
1 de diciembre de 2015 a las 5:48
-
Se votó a favor por mencionar “propiedad predeterminada”. ¡Hubo momentos en que necesité esto, pero lo olvidé!
– Vexen Crabtree
24 de junio de 2021 a las 11:56
mocoso
creo que lo que buscas es hasattr. Sin embargo, recomendaría algo como esto si desea detectar propiedades de pitón–
try:
getattr(someObject, 'someProperty')
except AttributeError:
print "Doesn't exist"
else
print "Exists"
La desventaja aquí es que los errores de atributo en las propiedades __get__
el código también se captura.
De lo contrario, haz-
if hasattr(someObject, 'someProp'):
#Access someProp/ set someProp
pass
Documentos:http://docs.python.org/library/functions.html
Advertencia:
El motivo de mi recomendación es que hasattr no detecta propiedades.
Enlace:http://mail.python.org/pipermail/python-dev/2005-December/058498.html
Según pydoc, hasattr(obj, prop) simplemente llama a getattr(obj, prop) y detecta excepciones. Por lo tanto, es tan válido envolver el acceso al atributo con una declaración de prueba y detectar AttributeError como usar hasattr() de antemano.
a = SomeClass()
try:
return a.fake_prop
except AttributeError:
return default_value
-
Bueno hasattr en realidad quizás optimizado Por ejemplo, con pypy.
– odinho – Velmont
18 de agosto de 2011 a las 17:37
-
+1. esto es incluso más seguro que usar
hasattr
cuandoSomeClass
anula__getattr__
ya quehasattr
cogerá todos excepciones en Python 2.x, no soloAttributeError
como esperarías. Esto se solucionó en Python 3.2; consulte mi otra respuesta para obtener una solución sencilla.– Martín Geisler
24 de abril de 2013 a las 7:47
maico
Me gustaría sugerir evitar esto:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
El usuario @jpalecek lo mencionó: Si un AttributeError
ocurre dentro doStuff()
estás perdido.
Tal vez este enfoque es mejor:
try:
val = a.property
except AttributeError:
otherStuff()
else:
doStuff(val)
-
Bueno hasattr en realidad quizás optimizado Por ejemplo, con pypy.
– odinho – Velmont
18 de agosto de 2011 a las 17:37
-
+1. esto es incluso más seguro que usar
hasattr
cuandoSomeClass
anula__getattr__
ya quehasattr
cogerá todos excepciones en Python 2.x, no soloAttributeError
como esperarías. Esto se solucionó en Python 3.2; consulte mi otra respuesta para obtener una solución sencilla.– Martín Geisler
24 de abril de 2013 a las 7:47
EDITAR:Este enfoque tiene serias limitaciones. Debería funcionar si el objeto es un iterable una. Por favor revise los comentarios a continuación.
Si estás usando Pitón 3.6 o superior como yo, hay una alternativa conveniente para verificar si un objeto tiene un atributo en particular:
if 'attr1' in obj1:
print("attr1 = {}".format(obj1["attr1"]))
Sin embargo, no estoy seguro de cuál es el mejor enfoque en este momento. usando hasattr()
usando getattr()
o usando in
. Los comentarios son bienvenidos.
-
in
la palabra clave funciona para verificar tipos iterables. Por ejemplo,'foo' in None
lanza el errorTypeError: argument of type 'NoneType' is not iterable
. La solución es verificar si el tipo es iterable antes de usarin
. Después de corregir los casos extremos como el tipo no iterable, probablemente sea mejor usarhasattr()
porque está diseñado para manejar los casos extremos.– Seth Difley
5 de octubre de 2017 a las 13:06
-
Esto no tiene nada que ver con el acceso a los atributos. No tengo idea de cómo fue votado. La única similitud que tiene para atribuir el acceso es si está utilizando
dict
como un “objeto liviano”, similar al diseño de objetos de JavaScript, pero la mayoría de las clases normales no admitirán esto en general (obteniendo una variante del error mencionado por @SethDifley).– ShadowRanger
25 de abril de 2018 a las 19:37
Cuando tu dices “decir si a tiene la propiedad de atributo antes de usarlo?” ¿Quieres una función que devuelva un valor booleano (como
hasattr()
regresa) o está bien lanzar unAttributeError
¿excepción?– smci
28 de febrero a las 4:04
Además, en realidad no nombre su atributo ‘propiedad’, porque Python tiene
property
decorador y construido también, y esos son ligeramente diferentes a los atributos/métodos normales.– smci
28 de febrero a las 4:07