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?

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top