hasattr() vs essayez-à l'exception du bloc pour faire face à l'absence d'attributs
if hasattr(obj, 'attribute'):
# do somthing
vs
try:
# access obj.attribute
except AttributeError, e:
# deal with AttributeError
Qui devrait être préféré et pourquoi?
Vous devez vous connecter pour publier un commentaire.
hasattr
en interne et rapidement effectue la même tâche que letry/except
bloquer: c'est un très spécifique, optimisé, une tâche de l'outil, et devrait donc être privilégiées, le cas échéant, à la très polyvalent alternative.hasattr
sera intercepter toutes les exceptions en Python 2.x. Voir ma réponse pour un exemple et le trivial solution de contournement.try
peut donner l'impression d'une opération de doit de travail. Sitry
l'objectif n'est pas toujours tel, il est fréquent, il peut donc être considéré comme plus lisible.Toute bancs qui illustrent la différence de performance?
timeit c'est votre ami
try
est deux fois plus rapide quehasattr()
. Si ça ne marche pas,try
est d'environ 1,5 x plus lent quehasattr()
(et les deux sont sensiblement plus lent que si l'attribut n'existe pas). C'est probablement parce que, sur le chemin d'accès joyeux,try
à peine n'importe quoi (Python est en train de payer pour les frais généraux d'exceptions, indépendamment de savoir si vous les utilisez), maishasattr()
nécessite une recherche de nom et d'appel de fonction. Sur le malheureux chemin, ils ont tous deux faire quelques manipulation d'exception et ungoto
, maishasattr()
t-il en C plutôt que de bytecode Python.Il ya un tiers, et souvent mieux, alternative:
Avantages:
getattr
ne pas avoir de mauvaise exception-de la déglutition comportement l'a souligné Martin Geiser - dans le vieux Pythons,hasattr
va même avaler unKeyboardInterrupt
.La raison habituelle pour vérifier si l'objet possède un attribut est de sorte que vous pouvez utiliser l'attribut, et cela conduit naturellement à elle.
L'attribut est de lire de façon atomique, et est à l'abri d'autres threads changer l'objet. (Si, si c'est une préoccupation majeure, vous pourriez envisager de verrouillage de l'objet avant d'y accéder.)
C'est plus courte que
try/finally
et souvent plus courte quehasattr
.Un large
except AttributeError
bloc peut attraper d'autresAttributeErrors
- vous que vous êtes enceinte, qui peut donner lieu à confusion comportement.Accéder à un attribut est plus lent que l'accès à une variable locale (surtout si c'est pas une simple instance de l'attribut). (Si, pour être honnête, micro-optimisation en Python est souvent sans issue.)
Une chose à faire attention est si vous vous souciez le cas où
obj.attribute
est défini sur Aucun, vous aurez besoin d'utiliser une sentinelle de la valeur.J'ai presque toujours utiliser
hasattr
: c'est le bon choix pour la plupart des cas.Le cas problématique, c'est quand une classe substitue
__getattr__
:hasattr
sera attraper toutes les exceptions au lieu de l'attraper justeAttributeError
comme vous vous attendez. En d'autres termes, le code ci-dessous impressionb: False
même s'il serait plus approprié de voir unValueError
exception:L'erreur importantes a donc disparu. Cela a été fixe en Python 3.2 (issue9666) où
hasattr
maintenant seulement attrapeAttributeError
.Une simple solution de contournement consiste à écrire une fonction d'utilité comme ceci:
Ce let's
getattr
face à la situation et il peut alors soulever l'exception appropriée.hasattr
permettra au moins de ne pas attraperKeyboardInterrupt
etc.safehasattr
, il suffit d'utilisergetattr
pour copier la valeur dans une variable locale si vous allez l'utiliser, qui vous avez presque toujours.hasattr
a été améliorée comme ça.hasattr
, et est allé vérifier. Nous avons eu quelques drôle bzr bugs où hasattr juste avalé ^C.Je dirais que cela dépend de la fonction peut accepter des objets sans l'attribut par la conception, par exemple, si vous avez deux appelants à la fonction, l'un fournissant un objet avec l'attribut et l'autre qui fournit un objet sans elle.
Si le seul cas où vous pouvez obtenir un objet sans l'attribut est due à une erreur, je vous conseille d'utiliser le mécanisme des exceptions, même si il peut être plus lent, parce que je crois que c'est un nettoyeur de conception.
Bottom line: je pense que c'est un de la conception et de la lisibilité problème plutôt que de l'efficacité de la question.
Si c'est juste un attribut que vous faites des tests, je dirais que l'utilisation
hasattr
. Toutefois, si vous êtes en train de faire plusieurs accède aux attributs qui peuvent exister ou non, puis à l'aide d'untry
bloc peut vous faire économiser un peu de temps.Si ce n'est avoir l'attribut est pas une condition d'erreur, la gestion de l'exception de la variante a un problème: il attrape aussi AttributeErrors qui pourrait venir en interne lors de l'accès à obj.attribut (par exemple parce que l'attribut est une propriété de sorte que l'accès il demande un peu de code).
Je vous suggère de l'option 2. L'Option 1 a une condition de concurrence si un autre thread est de l'ajout ou de la suppression de l'attribut.
Aussi python a une L'idiome, que l'aeap ("plus facile de demander pardon que la permission") est mieux que LBYL ('regarder avant de sauter').
À partir d'un point de vue pratique, dans la plupart des langues à l'aide d'un conditionnelle sera toujours consderably plus rapide que de la gestion d'une exception.
Si vous êtes désireux de traiter le cas d'un attribut n'existe pas quelque part à l'extérieur de la fonction courante, l'exception est la meilleure façon d'aller. Un indicateur que vous voudrez peut-être à l'aide d'une exception au lieu d'une condition, c'est que le conditionnel ne fixe un drapeau et s'interrompt l'opération en cours, et quelque chose d'ailleurs vérifie ce drapeau et d'agir sur cette base.
Cela dit, comme Rax Olgud points, la communication avec les autres est un attribut important de code, et ce que vous voulez dire en disant "c'est une situation exceptionnelle" plutôt que "c'est quelque chose que je attendre" peut-être plus important.
Ce sujet est couvert dans le EuroPython 2016 parler L'écriture plus rapide Python par Sebastian Witowski. Voici une reproduction de sa lame avec la synthèse des performances. Il utilise également la terminologie de regarder avant de sauter dans cette discussion, il convient de mentionner ici à la balise de mots clés.
3 LES AUTORISATIONS OU LE PARDON?
La première.
Plus court, c'est mieux. Les Exceptions doivent être exceptionnelles.
for
déclaration, ethasattr
utilise aussi. Cependant, "plus court, mieux c'est" (et "le plus simple est mieux"!) FAIRE appliquer, de sorte que le plus simple, plus court, plus spécifiques hasattr est en effet préférable.Au moins quand c'est juste ce qui se passe dans le programme, laissant de côté la partie humaine de la lisibilité, etc. (qui est en fait la plupart du temps plus importantes que les performances (au moins dans ce cas - avec des performances en durée), comme Roee Adler et d'autres ont souligné).
Néanmoins en regardant cela de ce point de vue,
il devient alors une question de choix entre
et
depuis
hasattr
utilise le premier cas, pour déterminer le résultat.De la nourriture pour la pensée 😉