75 votes

Meilleures pratiques pour les exceptions Python?

Quelles sont les meilleures pratiques pour la création d'exceptions? Je viens de voir cela, et je ne sais pas si je dois être horrifié, ou tout comme. J'ai lu plusieurs fois dans les livres que les exceptions ne devrait jamais contenir une chaîne, parce que les chaînes elles-mêmes peuvent lever des exceptions. Toute vérité à cela?

Essentiellement à partir de ma compréhension de la part des scripts, c'est que cela a été fait pour tous les internes bibliothèques Python aura un message d'erreur courants de format (quelque chose qui est désespérément nécessaire) afin que je puisse comprendre pourquoi leur mettre la chaîne de message d'erreur est une bonne idée. (Presque tous les jets de méthode exceptions en raison de l'absolue nécessité pour rien non valide passer à travers).

Le code en question est le suivant:

"""
Base Exception, Error
"""
class Error(Exception):
    def __init__(self, message):
        self.message = message

    def __str__(self):
        return "[ERROR] %s\n" % str(self.message)

    def log(self):
        ret = "%s" % str(self.message)
        if(hasattr(self, "reason")):
            return "".join([ret, "\n==> %s" % str(self.reason)])
        return ret

class PCSException(Error):
    def __init__(self, message, reason = None):
        self.message = message
        self.reason = reason
    def __str__(self):
        ret = "[PCS_ERROR] %s\n" % str(self.message)
        if(self.reason != None):
            ret += "[REASON] %s\n" % str(self.reason)
        return ret

C'est juste la pointe de l'iceberg, mais quelqu'un peut-il me donner un aperçu de ce qui rend ce une mauvaise idée? Ou si il y a une bien meilleure exception processus de codage/de style.

92voto

Eli Bendersky Points 82298

Gestion des exceptions robuste (en Python) - un article de blog "Meilleures pratiques pour les exceptions Python" que j'ai écrit il y a longtemps. Vous pouvez peut-être le trouver utile.

37voto

S.Lott Points 207588

J'ai lu plusieurs fois dans les livres qui les exceptions ne devrait jamais tenir une chaîne, car les chaînes elles-mêmes peuvent lancer des exceptions. Toute vérité vraie à cette?

Quoi?

Veuillez fournir une référence ou un lien vers le présent. C'est totalement faux.

Depuis, tous les objets peuvent lever des exceptions, aucun objet ne peut être contenue dans une exception par cette logique.

Non, le "no strings" est tout simplement fou dans un Python contexte. Peut-être que vous le lisez dans un C++ contexte.


Modifier

Once upon a time (retour dans les temps anciens) vous pourrait soulever un Python exception par nom et non par la classe réelle.

raise "SomeNameOfAnExceptionClass"

Ce qui est mauvais. Mais ce n'est pas y compris une chaîne de caractères à l'intérieur d'une exception. C'est de nommage de l'exception avec une chaîne, au lieu de la classe réelle de l'objet. Dans la version 2.5, cela peut encore travailler, mais obtient un warning de dépréciation.

C'est peut-être ce que vous lisez "Ne pas soulever une exception avec un nom de chaîne"

11voto

Graham Borland Points 27556

Je crois que le conseil contre la création d'exceptions avec une chaîne provient de "Learning Python" (O'Reilly). Dans une section intitulée Les exceptions de chaîne sont correctes! , il souligne la possibilité (désormais supprimée) de créer une exception directement avec une chaîne arbitraire.

Le code qu'il donne à titre d'exemple est:

 myexc = "My exception string"
try:
    raise myexc
except myexc:
    print ('caught')
 

C'est à la p858 de la quatrième édition (broché).

4voto

millimoose Points 22665

La première impression est que c'est tout à fait trop de code pour une exception.

Mise en forme des exceptions doit être fait dans l'enregistreur de configuration. En va de même pour l'enregistrement lui-même.

Il a également redéfinit la norme (et déconseillé) message d'attribut, et de ne pas appeler le constructeur de la superclasse. (Ce qui pourrait ou ne pourrait pas briser Python 3.0 exception de chaînage, je n'ai pas essayé parce que je suis en cours d'exécution 2.6)

La plupart de ce que le code supplémentaire ne peut être réalisé à l'aide d'BaseException.args, par l'enregistrement de l'après "message":

'\n==> '.join(exception.args)

Je dirais que si quelque chose peut être fait à l'aide d'un commun / idiomatiques mécanisme, il doit en particulier être fait dans la gestion des exceptions. (À l'exception d'un mécanisme pour signaler quelque chose à travers plusieurs couches de l'application.)

Personnellement, j'essaie d'éviter quelque chose au-delà

class SomeException(Exception): pass

(Avertissement: réponse subjective, peut-être par la nature de la question.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X