Quand dois-je sous-classer une exception en Python?

10

Dans mon code, il y a environ sept endroits où je soulève une exception. Toutes ces exceptions sont traitées de la même manière: imprimer une erreur dans le fichier journal, remettre l'état du logiciel par défaut et quitter.

Lors de l'examen du code, mon ingénieur principal, que j'apprécie beaucoup, a dit que je devrais sous-classer toutes ces exceptions. Son argument est qu'à l'avenir, nous voudrons peut-être traiter les exceptions différemment et ce sera plus facile.

Mon argument est qu'actuellement, cela ne fera qu'encombrer notre code et, comme nous ne savons pas si nous traiterons jamais les exceptions différemment, nous devrions laisser le code concis et, si et quand le moment viendra, alors et seulement alors nous devrions sous-taper .

J'aimerais entendre tout argument pour chaque cas.

Ezra
la source
2
YAGNI ... Vous n'en avez pas besoin maintenant et vous pouvez toujours l'ajouter plus tard sans trop de difficulté.
Robert Harvey
Avez-vous des exemples? Souhaitez-vous simplement soulever Exception, par exemple, ou des erreurs intégrées plus spécifiques?
jonrsharpe
levée d'une exception ("description spécifique")
Ezra
@Ezra au moins, vous devriez voir s'il existe une exception intégrée plus appropriée (voir docs.python.org/2/library/exceptions.html ).
jonrsharpe

Réponses:

8

Tu as raison

L'argument de votre côté est déjà mentionné par Robert Harvey: n'ajoutez pas de code dont vous n'avez pas besoin pour l'instant, d'autant plus qu'il est facile de l'ajouter plus tard.

Votre critique a également raison

D'un autre côté, le point de l'évaluateur est également compréhensible:

  • Le renvoi d'un générique Exception()n'est pas très utile à l'appelant: alors que la description de l'exception indique à un humain ce qui se passe, il peut être impossible de traiter les exceptions différemment par programme. Le développeur qui utilise votre code peut être réticent à changer les types d'exceptions , y compris par crainte (justifiée ou non) de casser quelque chose.

    Notez que l' ajout d'exceptions personnalisées en ce moment n'est pas si difficile :

    class MyCustomException(Exception):
        pass

    est tout ce dont vous avez besoin. Cela ne représente que deux lignes de code (étant donné que vous n'aurez peut-être même pas besoin de créer un fichier séparé si vous mettez des exceptions personnalisées dans un seul fichier).

  • Le code lui-même semble meilleur, plus lisible.

    if price < self.PriceMinValue:
        raise OutOfRangeException("The price is inferior to zero.")

    semble légèrement plus lisible par rapport à:

    if price < self.PriceMinValue:
        raise Exception("The price is inferior to zero.")

    en raison de l'indication du type d'exception:

    • Dans le deuxième morceau de code, je dois lire la description et deviner que le prix est hors de portée (ou peut-être pas? Peut-être qu'il y a des cas où le prix peut être négatif, comme les remises?)

    • Dans le premier morceau de code, un aperçu du type donne une indication immédiate de l'erreur. Il semble qu'il existe un ensemble de valeurs autorisées pour un prix et que la valeur actuelle se trouve en dehors de cet ensemble.

Donc?

Donc:

  • Les deux approches sont valables. Si vous ne sous-classez pas les exceptions lorsque vous n'avez pas besoin de types personnalisés, vous avez raison. Lorsque vous sous-classe les exceptions, car cela ne coûte rien de le faire et peut être utile plus tard, vous avez raison.

  • Soyez cohérent avec votre équipe. Si votre équipe utilise largement les exceptions personnalisées, utilisez-les.

Arseni Mourzenko
la source
2
Mais il y a un juste milieu: raise ValueError('The price is less than zero'). C'est plus spécifique que la base Exception, mais sans chichi.
jonrsharpe
+1 pour la simple déclaration "soyez cohérent", avec une équipe si vous en avez une, avec vous-même si vous n'en avez pas.
Styne666