Existe-t-il un moyen en Python pour 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?
python
attributes
Lucas Gabriel Sánchez
la source
la source
import string hasattr(string, "lower")
hasattr
est exactement la même chose que l'utilisation detry
/except AttributeError
: la docstring de hasattr (en Python 2.7) indique qu'elle utilise des exceptions de capture de main getattr.hasattr
n'est malheureusement pas exactement le même quetry: ... except AttributeError:
dans Python 2.x carhasattr
il interceptera toutes les exceptions . Veuillez consulter ma réponse pour un exemple et une solution de contournement simple.Comme Jarret Hardie a répondu,
hasattr
fera l'affaire. Je voudrais cependant ajouter que de nombreux membres de la communauté Python recommandent une stratégie «plus facile de demander pardon que permission» (EAFP) plutôt que de «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 Like a Pythonista: Idiomatic Python
c'est à dire:
... est préféré à:
la source
try:
devrait être la tentative d'accès aux attributs; il n'y a aucune raison de boucler également l'exécution dedoStuff
. Il existe cependant un certain potentiel d'ambiguïté: s'ilproperty
s'agit d'une propriété calculée au lieu d'un attribut simple, son implémentation pourrait augmenter enAttributeError
interne. C'est pourquoi dans presque toutes les situations réelles comme celle-ci,getattr
est préférable à l'unhasattr
ou à l'autreAttributeError
.Vous pouvez utiliser
hasattr()
ou attraperAttributeError
, mais si vous voulez vraiment juste la valeur de l'attribut avec un défaut s'il n'est pas là, la meilleure option est simplement d'utilisergetattr()
:la source
Je pense que ce que vous recherchez est hasattr . Cependant, je recommanderais quelque chose comme ça si vous voulez détecter les propriétés de python -
L'inconvénient ici est que les erreurs d'attribut dans le
__get__
code de propriétés sont également détectées.Sinon, faites-
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
la source
hasattr
détecte très bien les propriétés en général. C'est juste qu'il traite de lever une exception dans laproperty
fonction -wrapped comme signifiant qu'aucun tel attribut n'existe; la publication de liste de diffusion Python liée concerne une propriété qui déclenche une exception lorsque vous essayez d'y accéder. À toutes fins pratiques, cet attribut n'existe pas, car il ne produira jamais de valeur. En outre,hasattr
supprime uniquement les exceptions en général sur Py 3.1 et versions antérieures; dans 3.2+, il supprime seulement (en remplaçant parFalse
return)AttributeError
.Selon pydoc, hasattr (obj, prop) appelle simplement getattr (obj, prop) et intercepte les exceptions. Ainsi, il est tout aussi valide d'envelopper l'accès aux attributs avec une instruction try et d'attraper AttributeError que d'utiliser auparavant hasattr ().
la source
hasattr
lors desSomeClass
remplacements,__getattr__
car toutes les exceptions en Python 2.xhasattr
seront capturées, pas exactement comme vous vous y attendriez. Cela a été corrigé dans Python 3.2 - veuillez consulter mon autre réponse pour une solution de contournement simple.AttributeError
Je voudrais suggérer d'éviter cela:
L'utilisateur @jpalecek l'a mentionné: Si un
AttributeError
se produit à l'intérieurdoStuff()
, vous êtes perdu.Peut-être que cette approche est meilleure:
la source
Selon la situation, vous pouvez vérifier avec
isinstance
quel type d'objet vous disposez, 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 (les ABC permettent essentiellement une manière plus sophistiquée de taper du canard).Une situation où cela est utile serait si deux objets différents ont un attribut avec le même nom, mais avec une signification différente. Utiliser uniquement
hasattr
peut alors conduire à des erreurs étranges.Un bel exemple est la distinction entre les itérateurs et les itérables (voir cette question). Les
__iter__
méthodes d'un itérateur et d'un itérable ont le même nom mais sont sémantiquement assez différentes!hasattr
Est donc inutile, maisisinstance
avec ABC fournit une solution propre.Cependant, je conviens que dans la plupart des situations, l'
hasattr
approche (décrite dans d'autres réponses) est la solution la plus appropriée.la source
J'espère que vous attendez hasattr (), mais essayez d'éviter hasattr () et préférez getattr (). getattr () est plus rapide que hasattr ()
en utilisant hasattr ():
même ici, j'utilise getattr pour obtenir une propriété s'il n'y a pas de propriété, il ne retourne aucun
la source
EDIT : Cette approche a 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 supérieur comme moi, il existe une alternative pratique pour vérifier si un objet a un attribut particulier:
Cependant, je ne sais pas quelle est la meilleure approche en ce moment. en utilisant
hasattr()
, en utilisantgetattr()
ou en utilisantin
. Les commentaires sont les bienvenus.la source
in
Le mot clé fonctionne pour vérifier les types itérables. Par exemple,'foo' in None
jette l'erreurTypeError: argument of type 'NoneType' is not iterable
. Le correctif consiste à vérifier si le type est itérable avant utilisationin
. Après avoir corrigé les cas de bord comme le type non itérable, il est probablement préférable d'utiliserhasattr()
car il est conçu pour gérer les cas de bord.dict
comme un "objet léger", similaire à la conception d'objets JavaScript, mais la plupart des classes normales ne prendront pas en charge cela en général (obtenir une variante de l'erreur mentionnée par @SethDifley) .Voici une approche très intuitive:
la source
C'est super simple, il suffit d'utiliser l'
dir(
objet)
Cela retournera une liste de toutes les fonctions et attributs disponibles de l'objet.
la source
Une autre option possible, mais cela dépend de ce que vous entendez par avant :
production:
Cela vous permet même de vérifier les attributs sans valeur.
Mais! Faites très attention de ne pas instancier accidentellement et de comparer
undefined
plusieurs endroits caris
cela ne fonctionnera jamais dans ce cas.Mise à jour:
à cause de ce que j'avertissais dans le paragraphe ci-dessus, ayant plusieurs indéfinis qui ne correspondent jamais, j'ai récemment légèrement modifié ce modèle:
undefined = NotImplemented
NotImplemented
, à ne pas confondre avecNotImplementedError
, est un intégré: il correspond semi à l'intention d'un JSundefined
et vous pouvez réutiliser sa définition partout et il correspondra toujours. L'inconvénient est qu'il est "véridique" chez les booléens et qu'il peut paraître bizarre dans les journaux et les traces de pile (mais vous vous en remettez rapidement lorsque vous savez qu'il n'apparaît que dans ce contexte).la source
Vous pouvez vérifier si
object
contient un attribut à l'aide de lahasattr
méthode intégrée.Pour une instance si votre objet est
a
et que vous souhaitez vérifier l'attributstuff
La signature de la méthode elle-même est
hasattr(object, name) -> bool
ce qui signifie siobject
a un attribut qui est passé au deuxième argument danshasattr
ce qu'il donne booléenTrue
ouFalse
selon la présence d'name
attribut dans l'objet.la source
hasattr()
est la bonne réponse. Ce que je veux ajouter, c'est que celahasattr()
peut également être bien utilisé en conjonction avec assert (pour éviter lesif
instructions inutiles et rendre le code plus lisible):Comme indiqué dans une autre réponse sur SO : les assertions doivent être utilisées pour tester des conditions qui ne devraient jamais se produire. Le but est de planter tôt dans le cas d'un état de programme corrompu.
la source
hasattr
non pas le code environnant.