En Python, j'entends souvent dire qu'il est préférable de "demander pardon" (capture d'exception) au lieu de "demander l'autorisation" (vérification de type / condition). En ce qui concerne l'application de la frappe de canard en Python, est-ce que c'est
try:
x = foo.bar
except AttributeError:
pass
else:
do(x)
mieux ou pire que
if hasattr(foo, "bar"):
do(foo.bar)
else:
pass
en termes de performances, de lisibilité, de "pythonique" ou de tout autre facteur important?
exceptions
python
duck-typing
darkfeline
la source
la source
hasattr
est mis en œuvre avec cet essai / interception exact en interne. Pas sûr que ce soit vrai ... (j'agirais différemment sur les propriétés, n'est-ce pas?getattr
)hasattr
utilise l'équivalent C-API degetattr
(retourne enTrue
cas de succès,False
sinon), mais la gestion des exceptions en C est beaucoup plus rapide.Réponses:
Cela dépend vraiment de la fréquence à laquelle l’exception sera levée.
Les deux approches sont, à mon avis, également valables, du moins en termes de lisibilité et de pythonie. Mais si 90% de vos objets ne possèdent pas l'attribut,
bar
vous remarquerez une différence de performance nette entre les deux approches:Mais si 90% de vos objets n'ont l'attribut, les tables ont été transformées:
Du point de vue de la performance, vous devez donc choisir l’approche la mieux adaptée à votre situation.
En fin de compte, une utilisation stratégique du
timeit
module peut être la meilleure chose que vous puissiez faire en Pythonic.la source
hasattr
cela correspond en fait à l'équivalent C-api d'un essai - sauf sous le capot de toute façon, puisqu'il s'avère que le seul moyen général de déterminer si un objet a un attribut dans Python consiste à essayer d'y accéder.En python, vous obtenez souvent de meilleures performances lorsque vous faites les choses à la manière de Python. Avec d'autres langages, l'utilisation d'exceptions pour le contrôle de flux est généralement considérée comme une idée terrible car les exceptions imposent généralement une surcharge extraordinaire. Mais comme cette technique est explicitement approuvée en Python, l'interpréteur est optimisé pour ce type de code.
Comme pour toutes les questions relatives aux performances, la seule façon d’en être certain est de profiler votre code. Écrivez les deux versions et voyez laquelle est la plus rapide. Selon mon expérience, la "méthode Python" est généralement la méthode la plus rapide.
la source
Je pense que la performance est une préoccupation secondaire. Si cela se produit, un profileur vous aidera à vous concentrer sur les véritables goulots d'étranglement, ce qui peut être ou ne pas être la façon dont vous traitez les éventuels arguments illégaux.
La lisibilité et la simplicité, par contre, sont toujours une préoccupation majeure. Il n'y a pas de règles strictes ici, utilisez simplement votre jugement.
C'est un problème universel, mais les conventions spécifiques à l'environnement ou à la langue sont pertinentes. Par exemple, en Python, il est généralement préférable d’utiliser simplement l’attribut attendu et de laisser un éventuel AttributeError atteindre l’appelant.
la source
Pour ce qui est de l' exactitude , je pense que la gestion des exceptions est la voie à suivre (j'utilise parfois l'approche hasattr () moi-même, cependant). Le problème fondamental de hasattr () est qu’il transforme les violations de contrats de code en échecs silencieux (c’est un gros problème en JavaScript, qui ne jette pas sur des propriétés non existantes).
la source