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?
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.
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()
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')
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
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
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)
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.
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.
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