Existe-t-il un moyen dans 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 property
avant de l'utiliser?
Essayez hasattr()
:
if hasattr(a, 'property'):
a.property
EDIT: Voir réponse de zweiterlinde ci-dessous, qui offre de bons conseils pour demander pardon! Une approche très pythonique!
La pratique générale dans 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.
Comme Jarret Hardie a répondu, hasattr
fera l'affaire. Je voudrais cependant ajouter que beaucoup de membres de la communauté Python recommandent une stratégie consistant à "demander plus facilement pardon que 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()
Vous pouvez utiliser hasattr()
ou catch AttributeError
, mais si vous voulez vraiment juste la valeur de l'attribut avec une valeur par défaut si elle n'y est pas, la meilleure option consiste simplement à utiliser getattr()
:
getattr(a, 'property', 'default value')
Je pense que ce que vous cherchez, c'est hasattr . Cependant, je recommanderais quelque chose comme ceci si vous voulez détecter les propriétés du python -
try:
getattr(someObject, 'someProperty')
except AttributeError:
print "Doesn't exist"
else
print "Exists"
L'inconvénient est que les erreurs d'attribut dans les propriétés __get__
code sont également interceptées.
Sinon, ne-
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. Donc, il est tout aussi valide d'envelopper l'accès aux attributs avec une instruction try et d'attribuer AttributeError que d'utiliser hasattr () au préalable.
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
quel type d'objet vous avez, puis utiliser les attributs correspondants. Avec l'introduction de classes de base abstraites dans Python 2.6/3.0, cette approche est également devenue beaucoup plus puissante (fondamentalement, 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 this question). Les méthodes __iter__
dans un itérateur et un itérable ont le même nom mais sont très différentes sémantiquement! Donc, hasattr
est inutile, mais isinstance
avec 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 ()
en utilisant hasattr ():
if hasattr(a, 'property'):
print a.property
idem ici j'utilise getattr pour obtenir une propriété s'il n'y a aucune propriété retournée aucune
property = getattr(a,"property",None)
if property:
print property
EDIT: Cette approche a de sérieuses limites. Cela devrait fonctionner si l'objet est un iterable one. S'il vous plaît vérifier les commentaires ci-dessous.
Si vous utilisez Python 3.6 ou supérieur 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. en utilisant hasattr()
, en utilisant getattr()
ou en utilisant in
. Les commentaires sont les bienvenus.
Voici une approche très intuitive:
if 'property' in dir(a):
a.property
Une autre option possible, mais cela dépend de ce que vous entendez par avant:
undefined = object()
class Widget:
def __init__(self):
self.bar = 1
def zoom(self):
print("zoom!")
a = Widget()
bar = getattr(a, "bar", undefined)
if bar is not undefined:
print("bar:%s" % (bar))
foo = getattr(a, "foo", undefined)
if foo is not undefined:
print("foo:%s" % (foo))
zoom = getattr(a, "zoom", undefined)
if zoom is not undefined:
zoom()
sortie:
bar:1
zoom!
Cela vous permet même de vérifier les attributs sans valeur.
Mais! Faites très attention à ne pas instancier et comparer accidentellement undefined
plusieurs endroits car le is
ne fonctionnera jamais dans ce cas.
Vous pouvez vérifier si object
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 stuff
>>> class a:
... stuff = "something"
...
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False
La signature de la méthode elle-même est hasattr(object, name) -> bool
, ce qui signifie que si object
a attribut qui est passé au deuxième argument de hasattr
qu'il donne booléen True
ou False
en fonction de la présence de name
attribut dans object.
C'est super simple, utilisez juste dir(
objet)
Ceci retournera une liste de toutes les fonctions et attributs disponibles de l'objet.