2009-07-27 6 views
3

Je voudrais écrire une fonction dans Python (2.6) qui peut déterminer si elle est appelée à partir du code de gestion des exceptions quelque part dans la pile.En Python, comment savoir s'il est appelé par un code de gestion d'exception?

Ceci est destiné à une utilisation de journalisation spécialisée. Dans le module logging de python, l'appelant doit spécifier explicitement que les informations d'exception doivent être consignées (soit en appelant logger.exception(), soit en utilisant le mot-clé exc_info). Je voudrais que mon enregistreur le fasse automatiquement, selon qu'il est appelé depuis le code de gestion des exceptions.

Je pensais que vérifier sys.exc_info() pourrait être la réponse, mais il renvoie également des informations d'exception à partir d'une exception déjà traitée. (A partir du docs: "Cette fonction renvoie un ensemble de trois valeurs qui fournissent des informations sur l'exception actuellement gérée ... Si le cadre de pile actuel ne gère pas une exception, les informations sont extraites de la trame de la pile appelante, son appelant, et ainsi de suite jusqu'à ce qu'un cadre de pile se trouve qui est la manipulation d'exception. ici, « traitement d'une exception » est défini comme « l'exécution ou avoir exécuté une exception clause. » ")

en outre, puisque je veux que ceci soit transparent à l'appelant, je ne veux pas devoir employer exc_clear() ou n'importe quoi d'autre dans la clause except.

Quelle est la bonne façon de procéder?

+0

Comment le contexte d'appel peut-il être ambigu? Vous définissez une fonction ** à appeler à partir d'une exception **. C'est toujours appelé d'une exception. Quel est le problème? Veuillez donner une idée de la raison pour laquelle une fonction conçue pour être appelée à partir d'une exception ne serait pas appelée à partir d'une exception. –

+0

Je n'ai pas défini cela comme une fonction à appeler à partir d'une exception. C'est une fonction qui peut être appelée à partir d'une exception ou qui peut être appelée à partir d'une non-exception. Je veux déterminer quel est le cas. –

+1

Ummm ... Qu'est-ce qui ne va pas avec la définition de votre fonction pour qu'elle ** doive être appelée à partir d'une exception? Qu'est-ce qui vous empêche de changer la définition de la fonction pour simplifier cela? –

Répondre

2

Si vous supprimez l'exception à l'aide de sys.exc_clear dans vos gestionnaires d'exceptions, alors sys.exc_info devrait fonctionner pour vous. Par exemple: si vous exécutez le script suivant:

import sys 

try: 
    1/0 
except: 
    print sys.exc_info() 
    sys.exc_clear() 
print sys.exc_info() 

Vous devriez voir cette sortie:

 
(, ZeroDivisionError('integer division or modulo by zero',),) 
(None, None, None) 

Mise à jour: chemin Je ne crois pas qu'il y ait un simple ("transparent") de répondre à la question "Un gestionnaire d'exceptions est-il en cours d'exécution?" sans aller à des problèmes, et à mon avis, ça ne vaut pas la peine de prendre la peine juste pour la journalisation. Il est bien sûr facile de répondre à la question "Une exception a-t-elle été levée (dans ce fil)?", Même sur une base par pile (voir la documentation pour les objets frame).

+0

Merci Vinay, mais je cherche un moyen de faire cela qui soit transparent pour l'appelant; c'est-à-dire que cela n'exige rien de spécial dans la clause except. Je vais modifier la question pour être plus précis. –

0

Comme tout en Python, une exception est un objet. Par conséquent, vous pouvez conserver une référence (faible!) À la dernière exception gérée, puis utiliser sys.exc_info(). Remarque: dans le cas d'un code multithread, vous pouvez rencontrer des problèmes avec cette approche. Et il pourrait y avoir d'autres cas d'angle aussi bien. Cependant, explicit is better than implicit; Êtes-vous vraiment vraiment sûr que la manipulation de la journalisation des exceptions de la même manière que celle normale est une bonne fonctionnalité à ajouter à votre système?
À mon humble avis, non.

Questions connexes