¿Hay alguna forma en Python de 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 puede saber si atiene el atributo propertyantes de usarlo?

respuesta

Prueba 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, usar hasattrprobablemente sea más rápido que caer repetidamente en un bloque de excepción.

Como respondió Jarret Hardiehasattr , funcionará. 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 (estaba Re: un poco decepcionado hasta ahora)
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()

Puede 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')

Creo que lo que estás buscando es hasattr . Sin embargo, recomendaría algo como esto si desea detectar las propiedades de Python :

try:
    getattr(someObject, 'someProperty')         
except AttributeError:
    print "Doesn't exist"
else
    print "Exists"

La desventaja aquí es que también se detectan errores de atributo en el __get__código de propiedades.

De lo contrario, haz-

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

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

Me gustaría sugerir evitar esto:

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

El usuario @jpalecek lo mencionó: Si AttributeErrorocurre un dentro doStuff(), estás perdido.

Tal vez este enfoque es mejor:

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

EDITAR : este enfoque tiene una seria limitación. 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, 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.

Dependiendo de la situación, puede verificar con isinstancequé 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 también se ha vuelto mucho más poderoso (básicamente, los ABC permiten una forma más sofisticada de escribir 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. Usar solo hasattrpodría conducir a errores extraños.

Un buen ejemplo es la distinción entre iteradores e iterables (ver esta pregunta). ¡ Los __iter__métodos en un iterador y un iterable tienen el mismo nombre pero son semánticamente bastante diferentes! Por lo tanto hasattr, es inútil, pero isinstancejunto con ABC proporciona una solución limpia.

Sin embargo, estoy de acuerdo en que, en la mayoría de las situaciones, el hasattrenfoque (descrito en otras respuestas) es la solución más adecuada.

Espero que esperes hasattr(), pero intenta evitar hasattr() y 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 ninguna

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

Para objetos que no sean diccionarios:

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

Para el diccionario, hasattr()no funcionará.

Mucha gente dice que se use has_key()para el diccionario, pero está depreciado. Así que para el diccionario, tienes que usarhas_attr()

if a.has_attr('property'):
    a['property']
 

hasattr()es la respuesta correcta. Lo que quiero agregar es que hasattr()también se puede usar bien junto con afirmar (para evitar declaraciones innecesarias ify hacer que el código sea más legible):

assert hasattr(a, 'property'), 'object lacks property' 
print(a.property)

En caso de que falte la propiedad, el programa saldrá con AssertionErrore imprimirá el mensaje de error proporcionado ( object lacks propertyen este caso).

Como se indica en otra respuesta en SO :

Asserts should be used to test conditions that should never happen. The purpose is to crash early in the case of a corrupt program state.

A menudo, este es el caso cuando falta una propiedad y luego assertes muy apropiada.

Aquí hay un enfoque muy intuitivo:

if 'property' in dir(a):
    a.property

Esto es súper simple, solo use el dir(objeto)
. Esto devolverá una lista de todas las funciones y atributos disponibles del objeto.

Puede verificar si objectcontiene un atributo utilizando hasattrel método incorporado.

Por ejemplo, si su objeto es ay desea verificar el atributostuff

>>> class a:
...     stuff = "something"
... 
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False

La firma del método en sí es hasattr(object, name) -> boollo que significa que si objecttiene un atributo que se pasa al segundo argumento hasattr, entonces da un valor booleano Trueo Falsesegún la presencia del nameatributo en el objeto.

Otra opción posible, pero depende de lo que quieras decir antes :

undefined = object()

class Widget:

    def __init__(self):
        self.bar = 1

    def zoom(self):
        print("zoom!")

a = Widget()

bar = getattr(a, "bar", undefined)
if bar is not undefined:
    print("bar:%s" % (bar))

foo = getattr(a, "foo", undefined)
if foo is not undefined:
    print("foo:%s" % (foo))

zoom = getattr(a, "zoom", undefined)
if zoom is not undefined:
    zoom()

producción:

bar:1
zoom!

Esto le permite incluso verificar atributos sin valor.

¡Pero! Tenga mucho cuidado de no instanciar y comparar accidentalmente undefinedvarios lugares porque isnunca funcionará en ese caso.

Actualizar:

Debido a lo que estaba advirtiendo en el párrafo anterior, al tener múltiples indefinidos que nunca coinciden, recientemente modifiqué ligeramente este patrón:

undefined = NotImplemented

NotImplemented, que no debe confundirse con NotImplementedError, está integrado: casi coincide con la intención de un JS undefinedy puede reutilizar su definición en todas partes y siempre coincidirá. Los inconvenientes son que es "verdadero" en booleanos y puede parecer extraño en los registros y seguimientos de pila (pero lo supera rápidamente cuando sabe que solo aparece en este contexto).