¿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 puede saber si a
tiene el atributo property
antes de usarlo?
python
attributes
Lucas Gabriel Sánchez
fuente
fuente
import string hasattr(string, "lower")
hasattr
es exactamente lo mismo que usartry
/except AttributeError
: la cadena de documentación de hasattr (en Python 2.7) dice que usa excepciones de captura manual de getattr.hasattr
lamentablemente no es exactamente lo mismo quetry: ... except AttributeError:
en Python 2.x yahasattr
que detectará todas las excepciones . Consulte mi respuesta para ver un ejemplo y una solución simple.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). Ver estas referencias:EAFP vs LBYL (estaba Re: un poco decepcionado hasta el momento)
EAFP vs LBYL @Code Like a Pythonista: Idiomatic Python
es decir:
... se prefiere a:
fuente
try:
debería ser el intento de acceso al atributo; no hay razón para concluir la ejecucióndoStuff
también. Sin embargo, aún existe cierto potencial de ambigüedad: si seproperty
trata de una propiedad calculada en lugar de un atributo simple, su implementación podría aumentarAttributeError
internamente. Es por eso que en casi todas las situaciones reales como esta,getattr
es preferible a cualquierahasattr
o atraparAttributeError
.Puede usar
hasattr()
o capturarAttributeError
, pero si realmente solo desea el valor del atributo con un valor predeterminado si no está allí, la mejor opción es simplemente usargetattr()
:fuente
Creo que lo que estás buscando es hasattr . Sin embargo, recomendaría algo como esto si desea detectar las propiedades de Python :
La desventaja aquí es que los errores de atributo en el
__get__
código de propiedades también se detectan.De lo contrario, haga
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-December/058498.html
fuente
hasattr
detecta propiedades en general muy bien. Es solo que trata de generar una excepción en laproperty
función envuelta como si no existiera dicho atributo; la publicación de la lista de correo de Python vinculada trata sobre una propiedad que genera una excepción cuando intenta acceder a ella. Para todos los propósitos prácticos, dicho atributo no existe, porque nunca producirá un valor. Además,hasattr
solo suprime las excepciones en general en Py 3.1 y anteriores; en 3.2+, solo suprime (reemplazando conFalse
return)AttributeError
.Según pydoc, hasattr (obj, prop) simplemente llama a getattr (obj, prop) y captura 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.
fuente
hasattr
cuando seSomeClass
anula,__getattr__
yahasattr
que detectará todas las excepciones en Python 2.x, no soloAttributeError
como es de esperar. Esto se solucionó en Python 3.2: consulte mi otra respuesta para una solución simple.Me gustaría sugerir evitar esto:
El usuario @jpalecek lo mencionó: si
AttributeError
ocurre algo dentrodoStuff()
, está perdido.Quizás este enfoque sea mejor:
fuente
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 también se ha vuelto mucho más poderoso (básicamente, los ABC permiten una forma más sofisticada de tipear patos).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
hasattr
podría provocar errores extraños.Un buen ejemplo es la distinción entre iteradores e iterables (vea esta pregunta). ¡Los
__iter__
métodos en un iterador y un iterable tienen el mismo nombre pero son semánticamente bastante diferentes! Porhasattr
lo tanto, es inútil, peroisinstance
junto con ABC proporciona una solución limpia.Sin embargo, estoy de acuerdo en que, en la mayoría de las situaciones, el
hasattr
enfoque (descrito en otras respuestas) es la solución más adecuada.fuente
Espero que esperes hasattr (), pero trata de evitar hasattr () y prefiere getattr (). getattr () es más rápido que hasattr ()
usando hasattr ():
lo mismo aquí estoy usando getattr para obtener propiedad si no hay ninguna propiedad, no devuelve ninguna
fuente
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:
Sin embargo, no estoy seguro de cuál es el mejor enfoque en este momento. usando
hasattr()
, usandogetattr()
o usandoin
. Comentarios son bienvenidosfuente
in
la palabra clave funciona para verificar tipos iterables. Por ejemplo,'foo' in None
arroja el errorTypeError: argument of type 'NoneType' is not iterable
. La solución es verificar si el tipo es iterable antes de usarloin
. Después de corregir casos extremos como el tipo no iterable, probablemente sea mejor usarlohasattr()
porque está diseñado para manejar los casos extremos.dict
un "objeto ligero", similar al diseño de objetos JavaScript, pero la mayoría de las clases normales no admitirán esto en general (obteniendo una variante del error mencionado por @SethDifley) .Aquí hay un enfoque muy intuitivo:
fuente
Esto es súper simple, solo use
dir(
object)
Esto devolverá una lista de todas las funciones y atributos disponibles del objeto.
fuente
Otra opción posible, pero depende de a qué te refieres antes :
salida:
Esto le permite incluso verificar los atributos sin valor.
¡Pero! Tenga mucho cuidado de no crear instancias accidentalmente y comparar
undefined
varios lugares porqueis
nunca 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 he modificado ligeramente este patrón:
undefined = NotImplemented
NotImplemented
, que no debe confundirse conNotImplementedError
, es una función incorporada: coincide con la intención de un JSundefined
y puede reutilizar su definición en todas partes y siempre coincidirá. El inconveniente es que es "verdadero" en los booleanos y puede verse raro en los registros y los rastros de la pila (pero lo superas rápidamente cuando sabes que solo aparece en este contexto).fuente
Puede verificar si
object
contiene un atributo utilizando elhasattr
método incorporado.Por ejemplo, si su objeto es
a
y desea verificar el atributostuff
La firma del método en sí es lo
hasattr(object, name) -> bool
que significa siobject
tiene un atributo que se pasa al segundo argumento en lugarhasattr
de lo que da booleanoTrue
o deFalse
acuerdo con la presencia delname
atributo en el objeto.fuente
hasattr()
es la respuesta correcta Lo que quiero agregar es quehasattr()
también se puede usar bien junto con afirmar (para evitarif
declaraciones innecesarias y hacer que el código sea más legible):Como se indicó en otra respuesta sobre SO : Las afirmaciones deben usarse para probar condiciones que nunca deberían suceder. El propósito es colapsar temprano en el caso de un estado corrupto del programa.
fuente
hasattr
no el código circundante.