2010-12-12 87 views
19

Lorsque j'élève mes propres exceptions dans mes bibliothèques Python, la pile d'exceptions affiche la ligne d'élévation elle-même comme dernier élément de la pile. Ce n'est évidemment pas une erreur, c'est conceptuellement correct, mais pointe l'attention sur quelque chose qui n'est pas utile pour le débogage lorsque vous utilisez du code en externe, par exemple en tant que module.Ne pas afficher l'élévation Python dans la pile d'exceptions

Existe-t-il un moyen d'éviter cela et de forcer Python à afficher l'avant-dernier élément de la pile comme le dernier, comme les bibliothèques Python standard.

+7

La ligne de relèvement est masquée lorsqu'elle est levée à partir du code C compilé (car il n'y a pas de ligne de relèvement à afficher). Les parties Python des bibliothèques standard afficheront toujours l'instruction raise dans une traceback. –

+0

Peut-être que vous pourriez bidouiller 'sys.excepthook' pour exclure la dernière ligne s'il s'agit d'un' raise'. Mais généralement pas possible, s'y habituer. – delnan

+4

Vous pouvez toujours lever une exception utile. –

Répondre

7

Avertissement approprié: la modification du comportement de l'interpréteur est généralement désapprouvée. Et dans tous les cas, voir exactement où une erreur a été soulevée peut être utile dans le débogage, surtout si une fonction peut déclencher une erreur pour plusieurs raisons différentes.

Si vous utilisez le module traceback et que vous remplacez sys.excepthook par une fonction personnalisée, il est probablement possible de le faire. Mais faire la modification affectera l'affichage des erreurs pour l'ensemble du programme, pas seulement votre module, donc n'est probablement pas recommandé.

Vous pouvez également regarder le code put dans les blocs try/except, puis modifier l'erreur et l'augmenter de nouveau. Mais votre temps est probablement mieux passé à faire des erreurs inattendues improbables, et écrire des messages d'erreur informatifs pour ceux qui pourraient survenir.

-1

Je suggère de ne pas utiliser le mécanisme d'exception pour valider les arguments, aussi tentant que cela soit. Coder avec des exceptions comme conditionnelles, c'est comme si on disait: «plante mon application si, en tant que développeur, je ne pense pas à toutes les mauvaises conditions que mes arguments fournis peuvent causer.Peut-être utiliser des exceptions pour des choses non seulement hors de contrôle mais aussi sous contrôle d'autre chose comme le système d'exploitation ou le matériel ou le langage Python serait plus logique, je ne sais pas.En pratique, cependant, j'utilise des exceptions pour lesquelles vous demandez une solution

Pour répondre à votre question, en partie, il est tout aussi simple à coder ainsi:

class MyObject(object): 
    def saveas(self, filename): 
     if not validate_filename(filename): 
      return False 
     ... 

appelant

if not myobject.saveas(filename): report_and_retry() 

Peut-être pas une bonne réponse, juste quelque chose à penser.

+0

Je devais le faire parce que j'évitais autant d'exceptions que possible et que je disais à mon programme de m'en occuper, de passer au-dessus, de noter le problème et de continuer à marcher. J'ai eu plus de succès de débogage ici que de lancer des exceptions partout comme tout le monde le fait ... en gros j'utilise print() au lieu de relancer – Tcll

+0

Je viens de penser à l'autre côté de ça aussi, et probablement la raison La plupart des développeurs ne se contentent pas de lancer des exceptions pour n'importe quel mauvais cas d'utilisation, seuls les cas particuliers qui méritent une exception obtiennent une augmentation. ... accordé ce qui précède peut toujours arriver dans des cas particuliers même pas votre code attraperait. Par exemple: filename étant un objet représentant un str. – Tcll

4

Vous pouvez créer votre propre crochet d'exception en python. ci-dessous est l'exemple de code que j'utilise.

import sys 
import traceback 

def exceptionHandler(got_exception_type, got_exception, got_traceback): 
    listing = traceback.format_exception(got_exception_type, got_exception, got_traceback) 
    # Removing the listing of statement raise (raise line). 
    del listing[-2] 
    filelist = ["org.python.pydev"] # avoiding the debuger modules. 
    listing = [ item for item in listing if len([f for f in filelist if f in item]) == 0 ] 
    files = [line for line in listing if line.startswith(" File")] 
    if len(files) == 1: 
     # only one file, remove the header. 
     del listing[0] 
    print>>sys.stderr, "".join(listing) 

Et voici quelques lignes que j'ai utilisées dans mon code d'exception personnalisé.

sys.excepthook = exceptionHandler 
raise Exception("My Custom error message.") 

Dans l'exception de la méthode que vous pouvez ajouter des noms de fichiers ou noms de modules dans la liste « noms de fichiers » si vous voulez ignorer les fichiers indésirables. Comme j'ai ignoré le module pydeon pydev puisque j'utilise pydev debugger dans eclipse.

Ce qui précède est utilisé dans mon propre module dans un but spécifique. vous pouvez le modifier et l'utiliser pour vos modules.