Comment savoir si un objet a un attribut en Python
-
03-07-2019 - |
Question
Existe-t-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 savoir si a
a l'attribut propriété
avant de l'utiliser?
La solution
Essayez hasattr ()
:
if hasattr(a, 'property'):
a.property
ÉDITER: 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 de s'y trouver la plupart du temps, appelez-la simplement et laissez-la se propager, ou interceptez-la avec un bloc try / except. Ce sera probablement plus rapide que hasattr
. Si la propriété est susceptible de ne pas être présente la plupart du temps ou si vous n'êtes pas sûr, utiliser hasattr
sera probablement plus rapide que de tomber à plusieurs reprises dans un bloc d'exceptions.
Autres conseils
As Jarret Hardie , hasattr
fera l'affaire. J’aimerais cependant ajouter que de nombreux membres de la communauté Python recommandent une stratégie consistant à "demander plus facilement pardon que l’autorisation". (EAFP) plutôt que de "regarder avant de sauter" (LBYL). Voir ces références:
EAFP vs LBYL (Re: un peu déçu jusqu'à présent)
EAFP contre 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 capturer AttributeError
, mais si vous voulez vraiment que la valeur de l'attribut soit définie par défaut, le meilleur L’option est simplement d’utiliser getattr ()
:
getattr(a, 'property', 'default value')
Je pense que ce que vous recherchez, c'est hasattr . Cependant, je vous conseillerais quelque chose comme ceci si vous souhaitez détecter les propriétés de python -
.try:
getattr(someObject, 'someProperty')
except AttributeError:
print "Doesn't exist"
else
print "Exists"
L’inconvénient est que les erreurs d’attribut dans le code de propriétés __ get __
sont également interceptées.
Sinon, faites -
if hasattr(someObject, 'someProp'):
#Access someProp/ set someProp
pass
Docs: http://docs.python.org/library/functions.html
Avertissement:
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 getattr (obj, prop) et intercepte des exceptions. Par conséquent, il est tout aussi valide d'envelopper l'accès aux attributs avec une instruction try et d'attribuer AttributeError que d'utiliser hasattr () auparavant.
a = SomeClass()
try:
return a.fake_prop
except AttributeError:
return default_value
Je voudrais suggérer d'éviter ceci:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
L'utilisateur @jpalecek l'a mentionné: si un AttributeError
se produit dans doStuff ()
, vous êtes perdu.
Peut-être que cette approche est meilleure:
try:
val = a.property
except AttributeError:
otherStuff()
else:
doStuff(val)
En fonction de la situation, vous pouvez vérifier avec isinstance
le type d'objet que vous possédez, puis utiliser les attributs correspondants. Avec l’introduction des classes de base abstraites dans Python 2.6 / 3.0, cette approche a deviennent également beaucoup plus puissants (essentiellement, les ABC permettent une méthode de frappe plus sophistiquée).
Cela peut être utile si deux objets différents ont un attribut portant le même nom, mais avec une signification différente. Utiliser uniquement hasattr
pourrait alors entraîner des erreurs étranges.
Un bon exemple est la distinction entre itérateurs et 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 bien différentes! Donc hasattr
est inutile, mais isinstance
associé à ABC fournit une solution propre.
Cependant, je conviens que dans la plupart des situations, l'approche hasattr
(décrite dans d'autres réponses) est la solution la plus appropriée.
J'espère que vous attendez hasattr (), mais essayez d'éviter hasattr () et préférez s'il vous plaît getattr (). getattr () est plus rapide que hasattr ()
à l'aide de hasattr ():
if hasattr(a, 'property'):
print a.property
pareil, j'utilise getattr pour obtenir une propriété s'il n'y a pas de propriété renvoyée aucune
property = getattr(a,"property",None)
if property:
print property
MODIFIER : cette approche présente de sérieuses limites. Cela devrait fonctionner si l'objet est itérable . Veuillez vérifier les commentaires ci-dessous.
Si vous utilisez Python 3.6 ou plus, comme moi, il existe une alternative pratique pour vérifier si un objet possède 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. en utilisant hasattr ()
, en utilisant getattr ()
ou en utilisant dans
. Les commentaires sont les bienvenus.
Voici une approche très intuitive:
if 'property' in dir(a):
a.property
Vous pouvez vérifier si objet
contient un attribut en utilisant la méthode intégrée hasattr
.
Par exemple, si votre objet est a
et que vous souhaitez vérifier l'attribut substance
>>> class a:
... stuff = "something"
...
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False
La signature de la méthode elle-même est hasattr (objet, nom) - > bool
ce qui signifie que si objet
a attribut qui est passé au deuxième argument dans hasattr
qu'il donne boolean True
ou False
en fonction de la présence de l'attribut name
dans l'objet.
C’est très simple, utilisez simplement dir (
objet )
Ceci retournera une liste de toutes les fonctions et attributs disponibles de l'objet.