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?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top