2013-12-18 13 views
5

Ho il seguente codice:Python prova-se non con dei se altro

try: 
     pk = a_method_that_may_raise_an_exception() 
    except: 
     method_to_be_executed_in_case_of_exception_or_pk_is_false() 
    else: 
     if pk: 
      process_pk() 
     else: 
      method_to_be_executed_in_case_of_exception_or_pk_is_false() 

Questo potrebbe essere scritto come:

try: 
     if a_method_that_may_raise_an_exception(): 
      process_pk() 
     else: 
      method_to_be_executed_in_case_of_exception_or_pk_is_false() 
    except: 
     method_to_be_executed_in_case_of_exception_or_pk_is_false() 

io non sono felice che il metodo method_to_be_executed_in_case_of_exception_or_pk_is_false() appare due volte, vale a dire in altro di entrambi se e provare ... tranne.

C'è un modo migliore per farlo?

+2

Personalmente sarei più preoccupato di avere un nudo 'except' rispetto a chiamare la stessa funzione da due luoghi. Dovresti riscriverlo per prendere solo le eccezioni che ti aspetti vengano lanciate. – Duncan

+0

Nota che il tuo secondo esempio è _not_ equivalente al primo, dal momento che 'method_to_be_executed_in_case_of_exception_or_pk_is_false' potrebbe lanciare un'eccezione, causandone l'esecuzione due volte! – Eric

risposta

4

Si potrebbe provare la seguente:

class PKIsFalseException(Exception): 
    pass 

try: 
    pk = a_method_that_may_raise_an_exception() 
    if not pk: raise PKIsFalseException() 
except (PKIsFalseException, CatchableExceptions): 
    method_to_be_executed_in_case_of_exception_or_pk_is_false() 

Ho te preso atto di un'eccezione specifica che cattura invece tutte le eccezioni, che è sempre una cattiva pratica come altri hanno sottolineato. Supponendo che il tuo metodo genererà uno di CatchableExceptions.

+0

'assert' è solo per il debug. Può essere disabilitato e i programmi dovrebbero funzionare correttamente se 'assert' è disabilitato. – user2357112

+0

buon punto .. Immagino che possiamo solo aumentare l'eccezione in modo esplicito senza asserire per lo stesso effetto – qwwqwwq

+4

Come ho commentato sul post stesso, un '' eccetto 'è una cattiva idea. Allo stesso modo lanciare 'Exception()' non è buono; gettare sempre un'eccezione appropriata. In questo caso qualcosa come 'ValueError' potrebbe essere appropriato e il comando' except' dovrebbe quindi gestire solo le eccezioni previste, inclusa quella esplicitamente sollevata. – Duncan

-1
try: 
    if a_method_that_may_rise_an_exception(): 
     made_it = process_pk() 
except: 
    made_it = False 
if not made_it: 
    method_to_be_executed_in_case_of_exception_or_pk_is_false() 

?

+0

Hai bisogno di un 'eccetto' – SethMMorton

+0

@SethMMorton Haha, ti piace? Grazie! :) – Torxed

+1

Il problema qui è che anche 'process_pk()' potrebbe sollevare un'eccezione. In generale, è meno incline a inserire il minor numero possibile di codice nel gestore di eccezioni per ridurre il rischio di rilevare accidentalmente l'eccezione errata. – mgilson

10

Che dire qualcosa come:

try: 
    pk = a_method_that_may_rise_an_exception() 
except HandleableErrors: 
    pk = False 
finally: 
    if pk: 
     process_pk() 
    else: 
     method_to_be_executed_in_case_of_exception_or_pk_is_false() 

Davvero, non abbiamo neanche bisogno la clausola finally qui ...

try: 
    pk = a_method_that_may_rise_an_exception() 
except HandleableErrors: 
    pk = False 

if pk: 
    process_pk() 
else: 
    method_to_be_executed_in_case_of_exception_or_pk_is_false() 
0

Se si restituisce dalla funzione dopo, si potrebbe fare così:

try: 
    pk = a_method_that_may_rise_an_exception() 
except: 
    pass 
else: 
    if pk: 
     process_pk() 
     return 

method_to_be_executed_in_case_of_exception_or_pk_is_false()