Il rasoio di Occam:
More things should not be used than are necessary.
Python ti dà la possibilità di creare sottoclassi di eccezioni. Quella estensibilità è grande, quando ne hai bisogno. Ma è raro che tu abbia bisogno di farlo. Spesso è possibile ottenere lo stesso errore segnalando la chiarezza attraverso la personalizzazione del messaggio di un tipo di eccezione standard. Per esempio:.
def get_parsed_mail(mail):
if not mail.attachment:
raise ValueError('No attachment')
if not check_some_necessary_fields_format(mail):
raise ValueError('Invalid attachment field format')
Le eccezioni standard appartengono a una gerarchia ben strutturata e collaudata che molti sviluppatori hanno studiato e più o meno capiscono.
Le eccezioni personalizzate aiutano a segnalare il modulo che ha generato l'errore ("questo errore proviene da MailParser
!") e il suo tipo, ma spesso tali informazioni sono eccessive. Prendere in considerazione:
try:
mail_parts = ParseMail.parse(raw_message)
except Exception as e:
...
Visto nel contesto in cui verrà usato, la fonte non è un mistero. Sapete dal contesto che l'errore proviene da ParseMail
. Sai che è un MailNoAttachmentError
personalizzato o semplicemente un ValueError
.
Oltre alla fonte, diversi tipi di eccezione possono aiutarti a capire il tipo di errore. Cosa è successo, esattamente? La vera domanda è, distinguere quei tipi aiuta a rispondere alle condizioni di errore? Ti aspetti che ci siano gestori di errori per ognuno di questi diversi tipi di errore?
try:
mail_parts = ParseMail.parse(raw_message)
except MailNoAttachmentError as e:
...
except MailInvalidFieldError as e:
...
C'è qualcosa che un programma può fare per correggere quei singoli casi? O stai semplicemente segnalando allo sviluppatore / utente? Se si sta solo riportando a un essere umano, la personalizzazione del messaggio dell'eccezione è importante almeno quanto il tipo dell'eccezione. Probabilmente di più.
Quindi eccezioni personalizzate sono solo occasionalmente necessarie. Piggybacking di eccezioni standard, ma utilizzando i propri messaggi personalizzati, generalmente funziona altrettanto bene ed è più semplice.
Ma se ritieni che ci sia virtù in segnali di sorgente / tipo di errore più precisi, va bene anche questo. Un singolo tipo di errore personalizzato, solitamente derivato da un errore comune come ValueError
, è sufficiente per la maggior parte dei moduli, ad esempio:
class ParseMailError(ValueError):
pass
Se si desidera ottenere un'eccezione / precisione delle eccezioni Java-esque completa, è possibile creare la propria gerarchia di eccezioni ParseMail
unita alla gerarchia standard attraverso l'ereditarietà multipla:
class ParseMailError(Exception):
pass
class MailNoAttachmentError(ValueError, ParseMailError):
pass
class MailInvalidFieldError(TypeError, ParseMailError):
pass