Version courte:
Il y a une façon de réaliser dans Python le même effet obtenu par
carpe :: carpe code > utilitaire? p> blockQuote>
Version longue (pour ceux qui inconnus avec
carpe :: carpe code>): p>
Supposons que nous mettions implémenter une fonction d'API de bibliothèque (c'est-à-dire qu'il est censé être censé être utilisé par d'autres programmeurs dans leur em> code), disons
spam code> et supposons que
spam code> inclut un code pour vérifier la validité des arguments transmis . Bien entendu, ce code est censé soulever une exception si un problème de ces arguments est détecté. Disons que nous voulons rendre le message d'erreur associé et la traçabilité aussi utile que possible à quelqu'un de débogage du code client. P>
Idéalement, la dernière ligne de la traçabilité produite par cette exception soulevée doit identifier le "code fautif ", à savoir la ligne dans le code de la client em> où
spam code> a été appelé avec des arguments non valides. P>
Malheureusement, ce n'est pas ce qui se passerait, du moins par Par défaut, en utilisant Python. Au lieu de cela, la dernière ligne de la trace de traçage se référera à quelque part dans les internes du code de la bibliothèque, où l'exception était en réalité
élever code> d, qui serait assez obscure au public prévu de cette EM> Traceback particulier. p>
Exemple: P>
xxx pré> Lorsque nous exécutons
client.py code>, nous obtenons: p>
xxx pré> alors que ce que nous voulons se rapprocher de: p>
xxx pré> ... avec le code fautif (
x = SPAM (FALSE, FALSE) CODE>) En tant que dernière ligne de la traçabilité. p>
Ce dont nous avons besoin est un moyen de signaler l'erreur "du point de vue de l'appelant" (qui est ce que
Carp :: carpe code> Permet à Perl). P>
Edit: Juste pour être clair, cette question ne concerne pas Lbyl vs EAFP, ni sur les conditions préalables ou la programmation par contrat. Je suis désolé si j'ai donné cette mauvaise impression. Cette question concerne comment produire une trace de trace à partir de quelques niveaux (un, deux) sur la pile d'appels. P>
EDIT2: Python's
Traceback code> est un endroit évident à rechercher Un équivalent python de
carpe de Perl :: carpe code>, mais après l'avoir étudié pendant un certain temps, je ne pouvais trouver aucun moyen de l'utiliser pour ce que je veux faire. FWIW, Perl's's's's's's's's's's's's's> Carp :: Carp Code> permet un ajustement fin de la trame initiale pour la traçabilité en exposant la variable globale (par conséquent scopée de manière dynamique)
$ carpe :: Carplevel Code>. Fonctions de la bibliothèque non-API qui peut
carpe code> -out,
local code> -ormer et augmenter cette variable sur l'entrée (par exemple,
local $ carpe :: Carplevel + = 1; / code>). Je ne vois rien même à distance à distance em> comme ce module code> de la traçabilité code> de Python. Ainsi, sauf si j'ai manqué quelque chose, toute solution qui utilise le code> de Python's CODE> devrait prendre une claquette assez différente ... p> p>
3 Réponses :
Vous pouvez utiliser essayer..except code> dans la fonction API de niveau supérieur (
foo code>) pour soulever une exception différente:
class FooError(Exception): pass
def foo():
try:
bar()
except ZeroDivisionError:
raise FooError()
def bar():
baz()
def baz():
1/0
foo()
La traçabilité n'apparaîtrait toujours pas "du point de vue de l'appelant"
Il s'agit vraiment d'une question de convention, la manipulation des exceptions à Python est conçue pour être utilisée fortement (prier le pardon plutôt que de demander la permission). Et étant donné que vous travaillez dans un espace de langue différent, vous souhaitez suivre ces conventions - c'est-à-dire / vous souhaitez vraiment laisser les développeurs savoir où se trouvait le site de l'exception. Mais si vous avez vraiment besoin de faire cela ...
Inspecter le module fera à peu près tout ce dont vous avez besoin pour reconstruire une belle version de la carpe, qui fonctionne sans avoir à vous soucier des décorateurs (voir ci-dessous). Selon le commentaires dans cette réponse , c'est peut-être que Cette approche va rompre sur des pythons autres que cpython p> qui pour l'exemple suivant: p> produit la sortie: à l'aide de la traçabilité forte> p> C'était l'approche originale proposée. EM> P> P> P> P> P > Un équivalent à la carpe pourrait également être écrit en Python en manipulant des objets de voyageur, voir la documentation dans le Module . Le principal défi pour cela s'avère être injecté de l'exception et du code d'impression de trace. Il convient de noter que le code de cette section est très fragile. P> qui peut être appelé à l'aide du processus de base suivant: p> msg at foo.pl line 6
main::f() called at foo.pl line 10
main::g() called at foo.pl line 13
Je suis un peu familier avec le module de trace, mais je ne vois aucun moyen de l'utiliser pour ce que je veux faire. Si vous avez quelque chose de concret concret, cela vous aiderait à voir de la croquis de code de code. (Aussi, voir ma dernière modification, pour plus d'informations sur la façon dont $ carpe :: carpe code> résout ce problème.)
@kjo j'ai modifié ma réponse pour montrer une approche possible Utilisez le module de trace
@kjo, j'ai ajouté une deuxième solution permettant d'utiliser un python équivalent à la carpe sans aucun code de support.
Ce que vous voulez faire est appelé fonction d'établissement conditions préalables em> , et il n'y a pas de support de langue à Python. Python n'est également pas aussi parfaitement piraquable que Perl (sauf si vous utilisez peut-être si vous utilisez pypy), il ne peut donc pas être ajouté d'une manière entièrement transparente.
qui étant dit, le module pycontracts semble le faire relativement en douceur en utilisant des décorateurs de fonction et des spécifications de préconformation à base de cordes. Je n'ai pas utilisé le module moi-même, mais il semble que cela puisse vous obtenir quelque chose de plus près ce que vous voulez. Voici le premier exemple donné sur sa page d'information: p>