programacion - Cómo saber si un objeto tiene un atributo en Python
poo python 3 (9)
¿Hay una manera en Python para determinar si un objeto tiene algún atributo? Por ejemplo:
>>> a = SomeClass()
>>> a.someProperty = value
>>> a.property
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute ''property''
¿Cómo puedes saber si a
tiene la property
atributo antes de usarla?
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: Idiomatic Python
es decir:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
... se prefiere:
if hasattr(a, ''property''):
doStuff(a.property)
else:
otherStuff()
Creo que lo que buscas es hasattr . Sin embargo, recomendaría algo como esto si desea detectar propiedades de python :
try:
getattr(someObject, ''someProperty'')
except AttributeError:
print "Doesn''t exist"
else
print "Exists"
La desventaja aquí es que también se __get__
errores de atributos en las propiedades del código __get__
.
De lo contrario, do-
if hasattr(someObject, ''someProp''):
#Access someProp/ set someProp
pass
Docs: 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
De acuerdo con pydoc, hasattr (obj, prop) simplemente llama a getattr (obj, prop) y captura excepciones. Por lo tanto, es tan válido envolver el acceso de atributo con una declaración de prueba y capturar AttributeError como usar hasattr () de antemano.
a = SomeClass()
try:
return a.fake_prop
except AttributeError:
return default_value
Dependiendo de la situación, puede verificar con qué tipo de objeto tiene, y luego usar los atributos correspondientes. Con la introducción de las clases base abstractas en Python 2.6 / 3.0, este enfoque también se ha vuelto mucho más poderoso (básicamente, ABCs permite una forma más sofisticada de escribir pato).
Una situación en la que esto es útil sería si dos objetos diferentes tuvieran un atributo con el mismo nombre, pero con un significado diferente. Usar solo hasattr
puede llevar a errores extraños.
Un buen ejemplo es la distinción entre iteradores e iterables (consulte this pregunta). ¡Los métodos __iter__
en un iterador y un iterable tienen el mismo nombre pero son semánticamente muy diferentes! Por hasattr
tanto, hasattr
es inútil, pero la isinstance
junto con ABC proporciona una solución limpia.
Sin embargo, estoy de acuerdo en que en la mayoría de las situaciones, el enfoque hasattr
(descrito en otras respuestas) es la solución más adecuada.
Espero que esperen hasattr (), pero trate de evitar hasattr () y por favor prefiera getattr (). getattr () es más rápido que hasattr ()
utilizando hasattr ():
if hasattr(a, ''property''):
print a.property
Lo mismo aquí estoy usando getattr para obtener una propiedad si no hay ninguna propiedad no devuelve ninguna
property = getattr(a,"property",None)
if property:
print property
Me gustaría sugerir evitar esto:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
El usuario @jpalecek lo mencionó: si se produce un AttributeError
dentro de doStuff()
, estás perdido.
Tal vez este enfoque es mejor:
try:
val = a.property
except AttributeError:
otherStuff()
else:
doStuff(val)
Prueba hasattr()
:
if hasattr(a, ''property''):
a.property
EDITAR: Vea la respuesta de zweiterlinde a continuación, ¡quién ofrece buenos consejos para 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 no está seguro, usar hasattr
probablemente será más rápido que caer repetidamente en un bloque de excepción.
Puedes usar hasattr()
o capturar AttributeError
, pero si realmente solo quieres el valor del atributo con un valor predeterminado, si no está allí, la mejor opción es usar getattr()
:
getattr(a, ''property'', ''default value'')
EDITAR : Este enfoque tiene una seria limitación. Debería funcionar si el objeto es iterable . Por favor, compruebe los comentarios a continuación.
Si está usando Python 3.6 o superior como yo, hay una alternativa conveniente para verificar si un objeto tiene un atributo 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. utilizando hasattr()
, utilizando getattr()
o usando in
. Los comentarios son bienvenidos.