Cómo saber si un objeto tiene un atributo en Python
-
03-07-2019 - |
Pregunta
¿Hay alguna 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 el atributo propiedad
antes de usarlo?
Solución
Pruebe hasattr ()
:
if hasattr(a, 'property'):
a.property
EDITAR: consulte la respuesta de zweiterlinde a continuación, ¡que 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 no está seguro, usar hasattr
probablemente sea más rápido que caer repetidamente en un bloque de excepción.
Otros consejos
Como Jarret Hardie respondió, 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()
Puede usar hasattr ()
o capturar AttributeError
, pero si realmente solo desea el valor del atributo con un valor predeterminado si no está allí, la mejor La opción es solo usar getattr ()
:
getattr(a, 'property', 'default value')
Creo que lo que estás buscando 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 los errores de atributo en las propiedades del código __get__
también se detectan.
De lo contrario, do-
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-diciembre / 058498.html
Según pydoc, hasattr (obj, prop) simplemente llama a getattr (obj, prop) y captura las excepciones. Por lo tanto, es tan válido envolver el acceso al atributo con una instrucción try y atrapar AttributeError como usar hasattr () de antemano.
a = SomeClass()
try:
return a.fake_prop
except AttributeError:
return default_value
Me gustaría sugerir evitar esto:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
El usuario @jpalecek lo mencionó: si un AttributeError
ocurre dentro de doStuff ()
, estás perdido.
Quizás este enfoque sea mejor:
try:
val = a.property
except AttributeError:
otherStuff()
else:
doStuff(val)
Dependiendo de la situación, puede verificar con isinstance
qué tipo de objeto tiene, y luego usar los atributos correspondientes. Con la introducción de clases base abstractas en Python 2.6 / 3.0, este enfoque tiene también se vuelven mucho más poderosos (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
podría generar errores extraños.
Un buen ejemplo es la distinción entre iteradores e iterables (consulte iterable ). ¡Los métodos __iter__
en un iterador y un iterable tienen el mismo nombre pero son semánticamente bastante diferentes! Por lo tanto, hasattr
es inútil, pero 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 apropiada.
Espero que esperes hasattr (), pero trata de evitar hasattr () y prefiere getattr (). getattr () es más rápido que hasattr ()
usando hasattr ():
if hasattr(a, 'property'):
print a.property
igual aquí estoy usando getattr para obtener propiedad si no hay ninguna propiedad, no devuelve ninguna
property = getattr(a,"property",None)
if property:
print property
EDITAR : este enfoque tiene serias limitaciones. Debería funcionar si el objeto es iterable . Por favor revise los comentarios a continuación.
Si está utilizando Python 3.6 o superior como yo, existe 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. usando hasattr ()
, usando getattr ()
o usando en
. Los comentarios son bienvenidos.
Aquí hay un enfoque muy intuitivo:
if 'property' in dir(a):
a.property
Puede verificar si el objeto
contiene atributo utilizando el método integrado hasattr
.
Para una instancia si su objeto es a
y desea verificar el atributo stuff
>>> class a:
... stuff = "something"
...
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False
La firma del método en sí es hasattr (objeto, nombre) - > bool
que significa que si objeto
tiene atributo que se pasa al segundo argumento en hasattr
que da boolean True
o False
según la presencia del atributo name
en el objeto.
Esto es super simple, solo usa dir(
object )
Esto devolverá una lista de todas las funciones y atributos disponibles del objeto.