Pregunta Cómo saber si un objeto tiene un atributo en Python


¿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 property antes de usarlo?


1137
2018-03-04 14:45


origen


Respuestas:


Tratar hasattr():

if hasattr(a, 'property'):
    a.property

EDITAR: Ver 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ámala y deja que la excepción se propague o atrapa con un bloque try / except. Es probable que esto sea más rápido que hasattr. Si es probable que la propiedad no esté allí la mayor parte del tiempo, o no está seguro, use hasattr probablemente sea más rápido que caer repetidamente en un bloque de excepción.


1589
2018-03-04 14:48



Como Jarret Hardie contestada, hasattr hará el truco Me gustaría agregar, sin embargo, 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 el momento)
EAFP vs. LBYL @Code Like a Pythonista: Idiomatic Python

es decir:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

... es preferible a:

if hasattr(a, 'property'):
    doStuff(a.property)
else:
    otherStuff()

461
2018-03-04 14:56



Puedes usar hasattr() o atrapar 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')

370
2018-03-04 17:54



Creo que lo que estás buscando es Hasattr. Sin embargo, recomendaría algo así si quieres 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 atributos en las propiedades __get__ el código también está atrapado.

De lo contrario, hazlo

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.
Enlazar:http://mail.python.org/pipermail/python-dev/2005-December/058498.html


33
2018-03-04 14:52



De acuerdo con pydoc, hasattr (obj, prop) simplemente llama getattr (obj, prop) y atrapa excepciones. Por lo tanto, es igual de válido ajustar el acceso de atributo con una instrucción try y capturar AttributeError tal como está para usar hasattr () de antemano.

a = SomeClass()
try:
    return a.fake_prop
except AttributeError:
    return default_value

24
2018-03-04 14:56



Me gustaría sugerir evitar esto:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

El usuario @jpalecek lo mencionó: si AttributeError ocurre dentro doStuff(), estás perdido.

Tal vez este enfoque es mejor:

try:
    val = a.property
except AttributeError:
    otherStuff()
else:
    doStuff(val)

13
2017-08-26 13:04



Dependiendo de la situación, puede consultar con isinstance qué tipo de objeto tienes, y luego usa los atributos correspondientes. Con la introducción de clases base abstractas en Python 2.6 / 3.0, este enfoque también se ha vuelto mucho más poderoso (básicamente, los ABC permiten una forma más sofisticada de tipado de pato).

Una situación en la que esto es útil sería si dos objetos diferentes tienen un atributo con el mismo nombre, pero con un significado diferente. Usando solo hasattr podría conducir a errores extraños.

Un buen ejemplo es la distinción entre iteradores e iterables (ver esta pregunta). los __iter__ los métodos en un iterador y un iterable tienen el mismo nombre pero son semánticamente bastante diferentes. Asi que 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 hasattr enfoque (descrito en otras respuestas) es la solución más adecuada.


11
2018-03-04 15:41



EDITAR: Este enfoque tiene una seria limitación. Debería funcionar si el objeto es un iterable uno. Por favor revisa los comentarios a continuación.

Si estás usando Python 3.6 o superior como yo, existe 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. utilizando hasattr(), utilizando getattr() o usando in. Los comentarios son bienvenidos


9
2018-06-22 06:32



Espero que estés esperando hasattr (), pero trata de evitar hasattr () y por favor, prefiere getattr (). getattr () es más rápido que hasattr ()

usando hasattr ():

 if hasattr(a, 'property'):
     print a.property

Lo mismo aquí estoy usando getattr para obtener la propiedad si no hay ninguna propiedad, no devuelve ninguno

   property = getattr(a,"property",None)
    if property:
        print property

7
2017-12-30 07:49