2009-04-16 12 views

risposta

25

È buona norma non rilevare l'oggetto Eccezione radice, ma catturarne di più specifici, ad esempio IOException.

Considerare se si è verificata un'eccezione di memoria insufficiente: semplicemente l'utilizzo di "pass" non lascerà il programma in buono stato.

Praticamente l'unica volta che è necessario rilevare Eccezione si trova al livello più alto del programma, dove è possibile (provare a) registrarlo, visualizzare un errore ed uscire con la massima grazia possibile.

+2

questa cattiva abitudine genererà anche notevoli incubi di debug.Soprattutto quando altre eccezioni rispetto a quelle a cui hai pensato sono cresciute all'interno del tuo tentativo/eccetto. E questo semplicemente succede ... – vaab

3

perché pensa che stai prendendo troppo. ed è giusto.

1

Le eccezioni vengono sollevate quando si verifica qualcosa di eccezionale. In genere è una buona cosa che il programma termini.

Si potrebbe voler ignorare alcune eccezioni, ma IMO non c'è una buona ragione per catturare una classe base come quella.

+4

Ehi. Non penso di essere d'accordo sul fatto che "non c'è una buona ragione" - posso immaginare, ad esempio, un programma GUI che solleva un'eccezione quando si tenta una particolare operazione su un set di dati particolarmente insidioso. Va bene come programmatore dire che un'eccezione inaspettata dovrebbe terminare il programma con una traccia dello stack (fallire presto), ma in pratica ciò che l'utente vuole è che l'operazione corrente non funzioni correttamente, magari con un messaggio messagebox o logfile e quindi per la GUI per continuare a funzionare in modo che possano ad es salva i loro dati prima che accada qualcos'altro. –

+1

Sono assolutamente d'accordo, mi riferivo al modo in cui l'OP ignora le eccezioni con 'pass'. Avrei dovuto chiarire il mio punto. –

+0

Chiedete scusa, abbastanza equo allora. –

-1

Eccezione di cattura (senza controrilanciamento) ha 2 effetti collaterali molto negativi: gli errori vengono mangiati, quindi si perde la traccia di stack, ma anche che ctrl-c (o qualunque sia il tasto di interruzione sul sistema operativo) ottiene anche gestito qui.

Il comportamento tipico di programmi come questo è che non possono essere arrestati o che ctrl-c fa sì che il flusso di controllo salti in avanti (verso il gestore di eccezioni) e quindi continui. Quindi il codice non può essere interrotto, o è necessario martellare su ctrl-c per farlo arrestare.

+2

Questo non è più vero da Python 2.6, KeyboardInterrupt non eredita più da Exception. –

+0

Non perdere la traccia dello stack. Basta usare il modulo 'traceback' w/sys.exc_info(). – PeqNP

15

È buona norma catturare solo una gamma molto limitata di tipi. 'Eccezione' è troppo generica - finirai col prendere non solo gli errori che hai pianificato, ma anche altri errori, che potrebbero mascherare bug nel tuo codice che sarebbero più veloci da diagnosticare se non fossero stati catturati affatto, o forse essere gestito meglio da un unico gestore di eccezioni di altissimo livello.

Detto questo, dal momento che Python2.6, l'intercettazione di Eccezione è diventata molto più ragionevole, poiché tutte le eccezioni che non si desidera rilevare (SystemExit, KeyboardInterrupt) non ereditano più da Exception. Invece ereditano da una BaseException comune. Questo è stato fatto deliberatamente al fine di rendere la cattura Eccezione relativamente innocua, dal momento che è un tale idioma comune.

Vedere PEP 3110 per i dettagli & piani futuri.

0

come la risposta di Greg, "Eccezione" è una classe base ed è necessario ricavare eccezioni da questa classe, vedere anche exceptions.Exception.

Ecco un molto utile lista di errori in pydocs

Nota anche il modulo traceback molto utile che vi permette di scoprire dove si è verificato l'eccezione. Usando solo "tranne: ..." ti mostreremo quale errore dovresti usare nel tuo caso. Ad esempio, prova questo codice (alterna il commento), forse lo accetti:

import traceback 
#absent = 'nothing' 
try: 
    something = absent 
except NameError: 
    traceback.print_exc() 
else: 
    print("you get here only when you uncomment 'absent'") 
Problemi correlati