2016-11-20 1 views
1

Ich bin neugierig, ob es in Python eine Möglichkeit gibt, innerhalb von try/catch weiterzumachen, nachdem Sie eine Ausnahme gefunden haben, sehen Sie sich deren Eigenschaften an, und wenn nicht relevant, fahren Sie mit dem Stack fort.Python: Ausnahme Flow: Weiter nach unten Fang Block nach dem Fangen?

try: 
    # Code 
except AppleError as apple_ex: 
    # look at 'apple_ex.error_code' error body, and if not relevant, 
    # continue on to next down the catch block... 
    # In other words, proceed to except BananaError and so on down. 
except BananaError as banana_ex: 
    # ... 
except Exception as ex: 
    # ... 

Antwort

1

Ein AppleError ist immer noch ein AppleError und kein BananaError, auch wenn error_code nicht relevant ist, es macht also keinen Sinn, bis zu BananaError durchzukommen.

Sie könnten stattdessen spezifische Fehler für Ihre verschiedenen Fehlercodes definieren:

GRANNY_SMITH_ERROR = 1 
MACINTOSH_ERROR = 2 
class AppleError(Exception): 
    def __init__(self, error_code, *args): 
     super(AppleError, self).__init__(*args) 
     self.error_code = error_code 

class GrannySmithError(AppleError): 
    def __init__(self, *args): 
     super(GrannySmithError, self).__init__(GRANNY_SMITH_ERROR, *args) 

class MacintoshError(AppleError): 
    def __init__(self, *args): 
     super(MacintoshError, self).__init__(MACINTOSH_ERROR, *args) 

Dann können Sie versuchen, den spezifischen Fehler entsprechen:

try: raise MacintoshError() 
except MacintoshError as exc: print("mac") 
except GrannySmithError as exc: print("granny smith") 

Wenn Sie nicht zwischen verschiedenen Arten zu unterscheiden, ist es egal Von Apple-Fehler können Sie immer noch alle Apple-Fehler abfangen:

try: raise MacintoshError() 
except AppleError as exc: print("generic apple") 

Yo u kann diese zum Beispiel nur tun spezielle Verarbeitung für Grannysmith, nicht für Macintosh kombinieren:

try: raise MacintoshError() 
except GrannySmithError as exc: print("granny smith") 
except AppleError as exc: print("generic apple") 

Das Wichtigste der Fehler von den meisten spezifisch wenigsten spezifisch aufzulisten ist. Wenn Sie vor GrannySmithError auf AppleError testen, wird es niemals in den OmaSmith-Block eintreten.

2

Das ist nicht, wie Ausnahmen in Python behandelt werden. Wenn Sie eine Exception in einem try-Block auslösen, wenn Sie es in except fangen, wird es in diesen Block fallen, aber nicht weiter zum nächsten except auf der gleichen Ebene. Beachten Sie dieses Funktionsbeispiel:

try: 
    raise AttributeError() 
except AttributeError: 
    raise TypeError() 
except TypeError: 
    print("it got caught") # will not catch the TypeError raised above 

Also, in Ihrem try, erheben wir ein AttributeError, wir fangen, und heben Sie dann ein TypeError innerhalb der AttributeError zu kontrollieren.

Die except TypeError wird nicht fangen dassTypeError.

Je nachdem, wie Sie Ihr Problem erklären, müssen Sie überdenken, wie Sie Ihre Ausnahmen behandeln, und sehen, ob Sie die Fehlerbehandlung woanders bestimmen können, und den Fehler gibt.

Zum Beispiel:

def some_func(): 
    try: 
     thing() 
    except SomeException: 
     # analyze the exception here and raise the error you *should* raise 
     if apple_error_thing: 
      raise AppleError 
     elif banana_error_thing: 
      raise BananaError 
     else: 
      raise UnknownException 


def your_func(): 
    try: 
     some_func() 
    except AppleError as e: 
     print('Apple') 
    except BananaError as e: 
     print('Banana') 
    except UnknownException as e: 
     print('Unknown') 
1

Nein, das ist nicht möglich. Nachdem die Ausnahme von der inneren except gehandhabt hat es nicht die Fähigkeit, durch die äußere behandelt werden except:

Von the docs auf der try Aussage:

When the end of this block is reached, execution continues normally after the entire try statement. (This means that if two nested handlers exist for the same exception, and the exception occurs in the try clause of the inner handler, the outer handler will not handle the exception.)

Kurz Ihre einzige Lösung könnte sein, ein weiteren Behandlungsroutine an einer äußeren Ebene hat und raise die Ausnahme in der inneren Behandlungsroutine re-, das heißt:

try: 
    try: 
     raise ZeroDivisionError 
    except ZeroDivisionError as e: 
     print("caught") 
     raise ZeroDivisionError 
except ZeroDivisionError as f: 
    print("caught") 

Nun wird die verschachtelt except rais Es handelt sich um eine Ausnahme, die folglich von einem ähnlichen Handler erfasst wird.