2012-12-14 18 views
11

chcę zrobić:Jak napisać wiele instrukcji try w jednym bloku w python?

try: 
    do() 
except: 
    do2() 
except: 
    do3() 
except: 
    do4() 

Jeśli DO() nie powiedzie się, należy wykonać DO2(), jeśli DO2() nie powiedzie się też exceute DO3() i tak dalej.

pozdrawiam

+4

Mam wrażenie, że opisując swój specyficzny przypadek użycia doprowadzi do odpowiedzi z bardziej eleganckie rozwiązanie ... – Triptych

Odpowiedz

9

Chciałbym napisać funkcję szybkiego otoki first() dla tego.

Wykorzystanie: value = first([f1, f2, f3, ..., fn], default='All failed')

#!/usr/bin/env 


def first(flist, default=None): 

    """ Try each function in `flist` until one does not throw an exception, and 
    return the return value of that function. If all functions throw exceptions, 
    return `default` 

    Args: 
     flist - list of functions to try 
     default - value to return if all functions fail 

    Returns: 
     return value of first function that does not throw exception, or 
     `default` if all throw exceptions. 

    TODO: Also accept a list of (f, (exceptions)) tuples, where f is the 
    function as above and (exceptions) is a tuple of exceptions that f should 
    expect. This allows you to still re-raise unexpected exceptions. 
    """ 

    for f in flist: 
     try: 
      return f() 
     except: 
      continue 
    else: 
     return default 

# Testing. 

def f(): 
    raise TypeError 

def g(): 
    raise IndexError 

def h(): 
    return 1 


# We skip two exception-throwing functions and return value of the last. 
assert first([f, g, h]) == 1 

assert first([f, g, f], default='monty') == 'monty' 
0

należy określić typ wyjątku, który próbujesz złapać za każdym razem.

try: 
    do() 
except TypeError: #for example first one - TypeError 
    do_2() 
except KeyError: #for example second one - KeyError 
    do_3() 

i tak dalej.

+0

Jeśli nie wiem typ wyjątku? – alwbtc

+2

@alwbic: Jeśli nie znasz typu wyjątku, nie wiesz, jak sobie z nim poradzić. – BrenBarn

+0

@alwbic Jestem naprawdę pewien, że musisz wiedzieć, jakiego typu (ów) wyjątków oczekujesz. – alexvassel

21

Jeśli naprawdę nie obchodzi wyjątków, można pętli nad przypadkach aż ci się uda:

for fn in (do, do2, do3, do4): 
    try: 
     fn() 
     break 
    except: 
     continue 

to przynajmniej unika konieczności wciąć raz dla każdego przypadku. Jeśli różne funkcje wymagają różnych argumentów, możesz użyć functools.partial, aby "zaleczyć" je przed pętlą.

+1

'pass' powinno być' continue' maybe? Działa tak, jak napisano, ale 'continue' jest semantycznie czystszy. – Triptych

+0

@ Triptych To prawda, że ​​lepiej intonuje sygnał. Edytowana odpowiedź. –

4

Wydaje się naprawdę dziwne chce zrobić, ale prawdopodobnie pętli nad funkcjami i wybuchnąć, gdy nie było wyjątek podniesiony:

for func in [do, do2, do3]: 
    try: 
     func() 
    except Exception: 
     pass 
    else: 
     break 
0

Oto najprostszy sposób znalazłem, tylko osadzić spróbować ramach poprzedniego wyjątkiem.

try: 
    do() 
except: 
    try: 
     do2() 
    except: 
     do3() 
-1
import sys 

try: 
    f = open('myfile.txt') 
    s = f.readline() 
    i = int(s.strip()) 
except OSError as err: 
    print("OS error: {0}".format(err)) 
except ValueError: 
    print("Could not convert data to an integer.") 
except: 
    print("Unexpected error:", sys.exc_info()[0]) 
    raise 
+1

To wcale nie odpowiada na pytanie! –

Powiązane problemy