Le eccezioni di lancio sono costose nella maggior parte dei linguaggi di basso livello come C++. Ciò influenza molto la "saggezza comune" sulle eccezioni e non si applica tanto alle lingue che girano in una VM, come Python. Non c'è un costo così grande in Python per l'utilizzo di un'eccezione anziché di un condizionale.
(Questo è un caso in cui la "saggezza comune" diventa una questione di abitudine.Le persone provengono dall'esperienza in un tipo di ambiente - linguaggi di basso livello - e quindi la applicano a nuovi domini senza valutare se ha senso).
Le eccezioni sono ancora, in generale, eccezionali. Ciò non significa che non accadano spesso; significa che sono l'eccezione. Sono le cose che tendono ad uscire dal flusso di codice ordinario e che la maggior parte delle volte non si vuole gestire una per una, che è il punto di gestione delle eccezioni. Questa parte è la stessa in Python come in C++ e in tutte le altre lingue con eccezioni.
Tuttavia, questo tende a definire quando le eccezioni sono generate. Stai parlando di quando le eccezioni dovrebbero essere catturate. Molto semplicemente, non preoccuparti: le eccezioni non sono costose, quindi non andare troppo per cercare di evitare che vengano lanciate. Un sacco di codice Python è progettato attorno a questo.
Non sono d'accordo con il suggerimento di Jon di provare a testare ed evitare eccezioni in anticipo. Va bene se porta a un codice più chiaro, come nel suo esempio. Tuttavia, in molti casi complicherà le cose - può effettivamente portare a duplicare assegni e introdurre bug. Ad esempio,
import os, errno, stat
def read_file(fn):
"""
Read a file and return its contents. If the file doesn't exist or
can't be read, return "".
"""
try:
return open(fn).read()
except IOError, e:
return ""
def read_file_2(fn):
"""
Read a file and return its contents. If the file doesn't exist or
can't be read, return "".
"""
if not os.access(fn, os.R_OK):
return ""
st = os.stat(fn)
if stat.S_ISDIR(st.st_mode):
return ""
return open(fn).read()
print read_file("x")
Certo, possiamo testare ed evitare il fallimento - ma abbiamo complicato le cose male. Stiamo cercando di indovinare tutti i modi in cui l'accesso ai file potrebbe non riuscire (e questo non li cattura tutti), potremmo aver introdotto condizioni di gara e stiamo facendo molto più lavoro di I/O. Questo è tutto fatto per noi - basta prendere l'eccezione.
Il tuo codice mi sembra strano. 'heapify' trasforma un elenco * in posizione * in un heap. Come risultato di 'pq = heapq.heapify (a_list)', 'pq' sarà' None'. – stephan
Hai ragione! Errore stupido che ho fatto quando ho cercato di distillare il mio codice reale in qualcosa di adatto per un esempio. È riparato ora. –