Question Comment savoir si un objet a un attribut en Python


Y at-il un moyen en Python de déterminer si un objet a 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 pouvez-vous dire si a a l'attribut property avant de l'utiliser?


1137
2018-03-04 14:45


origine


Réponses:


Essayer hasattr():

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

EDIT: Voir La réponse de zweiterlinde ci-dessous, qui offre de bons conseils pour 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 laisser l'exception se propager, ou l'intercepter 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 si vous n'êtes pas sûr, en utilisant hasattr sera probablement plus rapide que de tomber à plusieurs reprises dans un bloc d'exception.


1589
2018-03-04 14:48



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

EAFP vs LBYL (était Re: Un peu déçu jusqu'à présent)
EAFP 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()

461
2018-03-04 14:56



Vous pouvez utiliser hasattr() ou attraper AttributeError, mais si vous voulez vraiment juste la valeur de l'attribut avec un défaut si ce n'est pas le cas, la meilleure option est juste d'utiliser getattr():

getattr(a, 'property', 'default value')

370
2018-03-04 17:54



Je pense que ce que vous cherchez est hasattr. Cependant, je recommanderais 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 capturés.

Sinon, faites-

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


33
2018-03-04 14:52



Selon pydoc, hasattr (obj, prop) appelle simplement getattr (obj, prop) et attrape les exceptions. Donc, il est tout aussi valide d'enrouler l'accès à l'attribut avec une instruction try et de capturer AttributeError comme il est d'utiliser hasattr () auparavant.

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

24
2018-03-04 14:56



Je voudrais suggérer d'éviter ceci:

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

L'utilisateur @jpalecek l'a mentionné: Si un AttributeError à l'intérieur doStuff(), vous êtes perdu.

Peut-être que cette approche est meilleure:

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

13
2017-08-26 13:04



Selon la situation, vous pouvez vérifier avec isinstance quel genre d'objet vous avez, puis utilisez les attributs correspondants. Avec l'introduction de classes de base abstraites en Python 2.6 / 3.0, cette approche est également devenue beaucoup plus puissante (en principe, les ABC permettent un typage plus sophistiqué du canard).

Une situation dans laquelle ceci serait utile serait que deux objets différents aient un attribut avec le même nom, mais avec une signification différente. En utilisant seulement hasattr pourrait alors conduire à d'étranges erreurs.

Un bon exemple est la distinction entre itérateurs et itérables (voir ce question). le __iter__ les méthodes dans un itérateur et une itérative ont le même nom mais sont sémantiquement assez différentes! Alors hasattr est inutile, mais isinstance avec ABC fournit une solution propre.

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


11
2018-03-04 15:41



MODIFIER: Cette approche a une limitation sérieuse. Cela devrait fonctionner si l'objet est un itérable un. S'il vous plaît vérifier les commentaires ci-dessous.

Si vous utilisez Python 3.6 ou plus haut comme moi il y a une alternative commode pour vérifier si un objet a un attribut particulier:

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

Cependant, je ne suis pas sûr de savoir quelle est la meilleure approche en ce moment. en utilisant hasattr(), en utilisant getattr() ou en utilisant in. Les commentaires sont les bienvenus.


9
2018-06-22 06:32



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

en utilisant hasattr ():

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

même ici j'utilise getattr pour obtenir la propriété s'il n'y a pas de propriété, il retourne aucun

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

7
2017-12-30 07:49