2013-12-18 9 views
5

Mam następujący kod:Python try-chyba od tego, czy innego

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() 

To może być zapisany jako:

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() 

nie jestem zadowolony, że metoda method_to_be_executed_in_case_of_exception_or_pk_is_false() pojawia się dwukrotnie, to znaczy w innym z nich, jeśli i spróbuj ... z wyjątkiem.

Czy jest lepszy sposób to zrobić?

+2

Osobiście byłbym bardziej martwi się o konieczności gołej 'except' niż nazywając tę ​​samą funkcję od dwóch miejscach. Powinieneś przepisać to, aby wychwycić tylko wyjątki, które spodziewałbyś się rzucić. – Duncan

+0

Zauważ, że twój drugi przykład nie jest równoważny z pierwszym, ponieważ 'method_to_be_executed_in_case_of_exception_or_pk_is_false' może sam rzucić wyjątek, powodując jego dwukrotne wykonanie! – Eric

Odpowiedz

4

można spróbować następujących czynności:

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() 

Mam cię pdated z konkretnym wychwytywaniem wyjątków, zamiast przechwytywać wszystkie wyjątki, co jest zawsze złym ćwiczeniem, jak wskazali inni. Zakładając, że twoja metoda wyrzuci jedną z CatchableExceptions.

+0

'assert' służy tylko do debugowania. Można go wyłączyć, a programy powinny działać poprawnie, jeśli wyłączono "assert". – user2357112

+0

dobra uwaga .. Myślę, że możemy po prostu jawnie podnieść wyjątek bez asserta dla tego samego efektu. – qwwqwwq

+4

Jak skomentowałem na samym wpisie, nagie 'except' jest złym pomysłem. Podobnie rzucanie 'Exception()' nie jest dobre; zawsze zgłaszaj odpowiedni wyjątek. W tym przypadku coś takiego jak "ValueError" może być odpowiednie, a 'except' powinno wtedy obsłużyć tylko wyjątki, które są oczekiwane, w tym jedno podniesione jawnie. – 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

Potrzebujesz 'z wyjątkiem' – SethMMorton

+0

@SethMMorton Haha, yepp robisz .. dziękuję! :) – Torxed

+1

Problem w tym, że 'process_pk()' również może wywołać wyjątek. Ogólnie rzecz biorąc, jest najmniej podatne na błędy, aby umieścić jak najmniej kodu w swoim sterowniku wyjątków, aby zmniejszyć ryzyko przypadkowego złapania niewłaściwego wyjątku. – mgilson

10

Co o czymś takim:

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() 

Naprawdę, my nawet nie potrzebują finally klauzuli tutaj ...

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

Po powrocie z funkcji potem, można zrobić to tak:

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()