web-dev-qa-db-fra.com

Comment savoir si un objet a un attribut dans Python

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?

1418

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.

2015
Jarret Hardie

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()
564
zweiterlinde

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')
430
Carl Meyer

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

39
batbrat

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
30
Jordan Lewis

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)
23
Maico

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.

12
nikow

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
11
Janarthanan Ramu

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.

9
nayak

Voici une approche très intuitive:

if 'property' in dir(a):
    a.property
1
Alec Alameddine

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.

0
JL Peyret

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.

0
Devang Padhiyar

C'est super simple, utilisez juste dir(objet)
Ceci retournera une liste de toutes les fonctions et attributs disponibles de l'objet.

0
Sean Christians