2013-07-16 2 views
5

Je voudrais savoir comment est la manière standard (s'il y en a) d'obtenir les exceptions qu'un module/fonction peut déclencher. Par exemple, json. Naturellement je suis allé à la Documentation mais je n'ai pas trouvé un moyen normalisé de savoir quelles exceptions peuvent être soulevées dans certaines fonctions (comme dump ou load). Ce n'est pas clair pour moi (à première vue) si juste attraper TypeError suffira.Comment trouver des exceptions qui peuvent être levées pour un module particulier en Python?

Quelles sont les recommandations pour être sûr que nous attrapons tout (et juste assez) sur un module/fonction particulier?

+0

Notez également: la documentation mentionne également 'ValueError'. – torek

Répondre

3

Je n'ai jamais été complètement satisfait de l'exception de Python. Cela fonctionne bien dans la pratique, c'est la théorie qui me dérange. :-) En particulier, parce que tout est dynamique, même si vous savez que evil() lève seulement ZorgError lui-même et appelle spam() ce qui soulève EggsError, de sorte que tout au plus vous obtenez ces deux erreurs d'un appel à evil(), quelqu'un pourrait mettre des choses derrière votre dos et changez cela.

Cela dit, certains documents sont meilleurs que d'autres. Par exemple os.kill peut évidemment augmenter OSError si le kill échoue, et TypeError si vous l'appelez avec quelque chose d'autre que deux nombres entiers, mais saviez-vous qu'il peut également augmenter ?

>>> os.kill(9999999999999, 0) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
OverflowError: signed integer is greater than maximum 

Si vous essayez d'écrire raisonnablement code épreuve des balles qui fait des choses comme lire un pid-file et de la sonde pour voir si un processus est en cours d'exécution, il s'avère que vous devez attraper ce OverflowError au cas où le pid dans le fichier pid est un entier, mais hors de portée. Ce serait bien si cela était dans la documentation (je l'ai trouvé par essais de la torture à la place.)

attraper simplement tout (except: ou except Exception) est généralement pas approprié car il attrape habituellement trop (y compris, par exemple, RuntimeError de un débordement de pile). Alors, comment savez-vous ce qu'il faut attraper? Je pense qu'il serait peut-être bon que les fonctions de feuille dans les bibliothèques standard aient un attribut "exceptions que j'élève directement" ou une exigence de documentation, mais ce n'est tout simplement pas là.


Edit: je l'ai mentionné dans un commentaire ci-dessus que la documentation JSON mentionne explicitement ValueError. Non explicitement appelé, mais trouvé dans les auto-tests de JSON, sont UnicodeDecodeError (ce qui est évident une fois que vous y pensez) et AttributeError (pas si évident). La documentation mentionne également que vous pouvez obtenir un OverflowError.Bien sûr, si vous utilisez json.dump, qui prend un flux sur lequel écrire, vous pouvez également obtenir toutes les erreurs du flux. Ce genre de chose est pourquoi une «liste d'exceptions zorg() soulève directement» n'est pas toujours très utile.

+0

J'apprécie votre réponse. C'est assez clair comment on peut manquer pour attraper une exception. Dans cet esprit, quelle est l'approche commune de Pythonic? Si c'est une fonction comme "os.kill", attrapez les états de la documentation et laissez les casse-tête? Et pour des modules pas très bien documentés comme 'json', juste attraper avec' Exception'? –

+0

Je ne suis pas sûr de "commun Pythonic". Il y a plusieurs problèmes à considérer. Parfois, l'endroit où l'on doit rattraper un échec est de niveau relativement élevé, donc vous voulez juste laisser les routines de bas niveau échouer et transmettre l'erreur. Parfois, l'endroit pour attraper un échec est juste quand il se produit. Parfois, l'objet n'est pas du tout «rattraper l'échec», mais plutôt de nettoyer (par exemple, déverrouiller une structure de données), auquel cas vous voulez un bloc 'try' avec un contexte de style' finally' ou 'with ' directeur. J'ai cependant trouvé un consensus général sur le fait que «excepté l'exception» est rarement juste. – torek

2

Eh bien, vous pouvez utiliser le type global Exception-catch le Exceptions:

try: 
    1 + "2" 
except Exception as error: 
    print "Error", error 

La sortie sera quelque chose comme:

Error unsupported operand type(s) for +: 'int' and 'str' 

Si vous voulez connaître le nom de cette exception, vous pouvez faire quelque chose comme:

try: 
    1 + "2" 
except Exception as error: 
    print error.__class__.__name__, error 

et e La sortie sera quelque chose comme:

TypeError unsupported operand type(s) for +: 'int' and 'str' 
+0

Merci d'avoir posté un moyen pratique d'obtenir des noms d'exceptions. Le problème principal est que je n'ai pas le 'code' avancé pour savoir quelles exceptions peuvent être levées. Je pensais juste que je pourrais trouver un moyen d'avoir une documentation exhaustive des exceptions sur un module particulier. –

+0

De rien, je pense que c'est bon d'attraper 'Exceptions' parce que parfois le doc d'un module est mauvais ou parfois vous ne connaissez pas le type' Exception' qu'une bibliothèque peut générer. –

Questions connexes