Comment savoir si un objet possède un attribut en Python

y a-t-il un moyen en Python de déterminer si un objet possède un attribut? Par exemple:

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

Comment savoir si a possède l'attribut property avant de l'utiliser?

1181
demandé sur Dana 2009-03-04 17:45:59

9 réponses

Essayer hasattr() :

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

EDIT: Voir zweiterlinde la réponse de ci-dessous, qui offre de bons conseils sur le point de demander pardon! Une approche très pythonique!

la pratique générale en python est que, si la propriété est susceptible d'être là la plupart du temps, il suffit de l'appeler et soit laisser l'exception se propager, soit la piéger avec un bloc try/except. Ce sera probablement plus rapide que hasattr . Si la propriété est susceptible de ne pas être là la plupart du temps, ou vous n'êtes pas sûr, en utilisant hasattr sera probablement plus rapide que de tomber à plusieurs reprises dans un bloc d'exception.

1659
répondu Jarret Hardie 2018-03-21 19:26:12

Comme Jarret Hardie , a répondu, hasattr fera l'affaire. Je voudrais ajouter, cependant, que beaucoup dans la communauté Python recommandent une stratégie de "plus facile à demander le pardon que la permission" (EAFP) plutôt que de "regarder avant de sauter" (LBYL). Voir ces références:

l'aeap vs LBYL (était Re: Un peu déçu jusqu'à présent)

l'aeap vs LBYL @Code Comme un Pythonista: Python Idiomatique

c'est à dire:

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

... est préféré à:

if hasattr(a, 'property'):
    doStuff(a.property)
else:
    otherStuff()
476
répondu zweiterlinde 2018-05-27 09:30:53

vous pouvez utiliser hasattr() ou "catch AttributeError , mais si vous voulez vraiment juste la valeur de l'attribut avec un défaut si elle n'est pas là, la meilleure option est juste d'utiliser getattr() :

getattr(a, 'property', 'default value')
383
répondu Carl Meyer 2013-09-24 20:22:25

je pense que ce que vous cherchez est hasattr . Cependant, je recommande quelque chose comme ceci si vous voulez détecter propriétés python -

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

l'inconvénient ici est que les erreurs d'attribut dans les propriétés __get__ code sont également attrapées.

sinon, do -

if hasattr(someObject, 'someProp'):
    #Access someProp/ set someProp
    pass

Docs: http://docs.python.org/library/functions.html

attention:

La raison de ma recommandation est que hasattr ne détecte pas les propriétés.

Lien: http://mail.python.org/pipermail/python-dev/2005-December/058498.html

35
répondu batbrat 2009-03-04 15:29:11

selon pydoc, hasattr(obj, prop) appelle simplement des exceptions getattr (obj, prop) et catches. Ainsi, il est tout aussi valable d'envelopper l'accès à l'attribut d'une instruction try et de capturer AttributeError que d'utiliser hasattr() à l'avance.

a = SomeClass()
try:
    return a.fake_prop
except AttributeError:
    return default_value
27
répondu Jordan Lewis 2009-03-04 14:56:26

je voudrais suggérer d'éviter cela:

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

l'utilisateur @jpalecek l'a mentionné: si un AttributeError se produit à l'intérieur de doStuff() , vous êtes perdu.

peut-être que cette approche est meilleure:

try:
    val = a.property
except AttributeError:
    otherStuff()
else:
    doStuff(val)
14
répondu Maico 2016-08-26 13:04:30

Selon la situation, vous pouvez vérifier avec isinstance quel type d'objet que vous avez, puis utilisez les attributs correspondants. Avec l'introduction de abstract base classes en python 2.6 / 3.0 cette approche est également devenue beaucoup plus puissante (essentiellement ABCs permettent une façon plus sophistiquée de canard dactylographier).

une situation où ceci est utile serait si deux objets différents ont un attribut avec le même nom, mais avec sens différent. Utiliser seulement hasattr pourrait alors conduire à des erreurs étranges.

un bel exemple est la distinction entre les itérateurs et les itérables (voir cette question ). Les méthodes __iter__ dans un itérateur et un itérable ont le même nom mais sont sémantiquement très différentes! Donc hasattr est inutile, mais isinstance avec ABC fournit une solution propre.

cependant, je suis d'accord que dans la plupart des situations l'approche hasattr (décrite dans d'autres réponses) est la solution la plus appropriée.

11
répondu nikow 2017-05-23 12:26:34

EDIT : cette approche a de sérieuses limites. Cela devrait fonctionner si l'objet est un itératif . Veuillez consulter les commentaires ci-dessous.

si vous utilisez Python 3.6 ou plus haut comme moi, il existe une alternative pratique pour vérifier si un objet a un attribut particulier:

if 'attr1' in obj1:
    print("attr1 = {}".format(obj1["attr1"]))

cependant, je ne sais pas quelle est la meilleure approche pour le moment. utiliser hasattr() , en utilisant getattr() ou in . Les commentaires sont les bienvenus.

10
répondu nayak 2018-04-26 08:54:31

J'espère que vous attendez hasattr (), mais essayez d'éviter hasattr () et s'il vous plaît préférez getattr (). getattr () est plus rapide que hasattr ()

utilisant hasattr ():

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

même ici j'utilise getattr pour obtenir des biens s'il n'y a pas de biens qu'il retourne aucun

   property = getattr(a,"property",None)
    if property:
        print property
9
répondu Janarthanan Ramu 2017-05-22 05:47:18