803 Stimmen

Welchen Zweck erfüllt die optionale "else"-Klausel der "try"-Anweisung in Python?

Was ist der Verwendungszweck der optionalen else Klausel des try Aussage?

5 Stimmen

Die meisten Antworten scheinen sich darauf zu konzentrieren, warum wir das Material in der else-Klausel nicht einfach in die try-Klausel selbst einfügen können. Die Frage stackoverflow.com/questions/3996329 fragt ausdrücklich, warum der Code der else-Klausel nicht gehen kann nach der Try-Block selbst, und diese Frage ist mit dieser hier verknüpft, aber ich sehe hier keine klare Antwort auf diese Frage. Ich glaube stackoverflow.com/a/3996378/1503120 beantwortet diese Frage in hervorragender Weise. Ich habe auch versucht, die verschiedenen Bedeutungen der einzelnen Klauseln zu erläutern stackoverflow.com/a/22579805/1503120 .

2 Stimmen

Wenn die Ausnahme nicht auslöst, soll vor der abschließenden Bereinigung etwas geschehen, das nicht selbst die gleiche Ausnahmebehandlung auslösen soll.

5 Stimmen

Nachdem ich vergessen hatte, was else tut in try/else y for/else Ich habe es mehrmals mit dem Begriff noexcept y nobreak in diesen jeweiligen Zusammenhängen. Ich persönlich halte es für eine so unglückliche Überfrachtung des Wortes, dass ich versuche, es nach Möglichkeit zu vermeiden, da es die Leute, die den Code lesen, dazu zwingt, sich zu fragen: "Was macht dieses Ding nochmal?" Normalerweise ist ein Flag, eine continue o break Aussage kann das, was ich ausdrücken will, mit wenigen zusätzlichen Zeilen, aber sicherlich mit mehr Klarheit wiedergeben (wenn die Popularität der Frage ein Hinweis darauf ist).

151voto

Izkata Punkte 8632

Es gibt eine groß Grund für die Verwendung else - Stil und Lesbarkeit. Es ist im Allgemeinen eine gute Idee, Code, der Ausnahmen verursachen kann, in der Nähe des Codes zu halten, der sich mit ihnen befasst. Vergleichen Sie zum Beispiel diese:

try:
    from EasyDialogs import AskPassword
    # 20 other lines
    getpass = AskPassword
except ImportError:
    getpass = default_getpass

y

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
else:
    # 20 other lines
    getpass = AskPassword

Die zweite ist gut, wenn die except kann nicht vorzeitig zurückkehren oder die Ausnahme erneut auslösen. Wenn möglich, würde ich geschrieben haben:

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
    return False  # or throw Exception('something more descriptive')

# 20 other lines
getpass = AskPassword

Note : Antwort von kürzlich veröffentlichtem Duplikat kopiert aquí daher der ganze "AskPassword"-Kram.

82voto

Python try-else

Was ist der Verwendungszweck der optionalen else Klausel der try-Anweisung?

Die beabsichtigte Verwendung ist es, einen Kontext für mehr Code zu haben, der ausgeführt werden kann, wenn es keine Ausnahmen gab, wo es erwartet wurde, behandelt zu werden.

Dadurch wird vermieden, dass versehentlich Fehler behandelt werden, die Sie nicht erwartet haben.

Es ist jedoch wichtig, die genauen Bedingungen zu verstehen, die dazu führen, dass die else-Klausel ausgeführt wird, denn return , continue et break kann den Kontrollfluss unterbrechen, um else .

Zusammenfassung

Le site else Anweisung läuft, wenn es ノー Ausnahmen und wenn nicht unterbrochen durch eine return , continue , oder break Erklärung.

In den anderen Antworten fehlt dieser letzte Teil.

Aus den Unterlagen:

Die fakultative else Klausel wird ausgeführt, wenn und sobald die Kontrolle fließt aus dem Ende der try Klausel.*

(Fettdruck hinzugefügt.) Und die Fußnote lautet:

*Gegenwärtig fließt die Kontrolle "vom Ende weg", außer im Falle einer Ausnahme oder der Ausführung eines return , continue , oder break Erklärung.

Sie erfordert mindestens eine vorangehende Ausnahmeklausel ( siehe die Grammatik ). Es handelt sich also nicht um "try-else", sondern um "try-except-else(-finally)", wobei die else (und finally ), die fakultativ sind.

Le site Python-Anleitung wird der Verwendungszweck näher erläutert:

Die Anweisung try ... except hat eine optionale else-Klausel, die, wenn sie vorhanden ist, allen except-Klauseln folgen muss. Sie ist nützlich für Code, der ausgeführt werden muss, wenn die try-Klausel keine Ausnahme auslöst. Für Beispiel:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'cannot open', arg
    else:
        print arg, 'has', len(f.readlines()), 'lines'
        f.close()

Die Verwendung der else-Klausel ist besser als das Hinzufügen von zusätzlichem Code zur Try-Klausel hinzuzufügen, weil dadurch vermieden wird, dass versehentlich eine Ausnahme abgefangen wird die nicht durch den Code ausgelöst wurde, der durch die try ... except Anweisung geschützt ist.

Beispiel zur Differenzierung else gegenüber dem Code nach der try Block

Wenn Sie einen Fehler behandeln, wird die else Block wird nicht ausgeführt. Zum Beispiel:

def handle_error():
    try:
        raise RuntimeError('oops!')
    except RuntimeError as error:
        print('handled a RuntimeError, no big deal.')
    else:
        print('if this prints, we had no error!') # won't print!
    print('And now we have left the try block!')  # will print!

Und jetzt,

>>> handle_error()
handled a RuntimeError, no big deal.
And now we have left the try block!

2 Stimmen

Hauptpunkt aus den Unterlagen: "Die Verwendung des else Klausel ist besser als das Hinzufügen von zusätzlichem Code in der try Klausel, weil sie verhindert, dass versehentlich eine Ausnahme abgefangen wird, die nicht durch den Code ausgelöst wurde, der durch die try ... except Erklärung".

0 Stimmen

Ich denke, das ist die beste Erklärung. Danke Aaron.

0 Stimmen

Der Kommentar von @starriet ist klar und prägnant. Wollte nur hervorheben, da dieser Kommentar zu dieser (bereits guten) Antwort beiträgt.

68voto

Darius Bacon Punkte 14645

Eine Verwendung: Testen Sie einen Code, der eine Ausnahme auslösen soll.

try:
    this_should_raise_TypeError()
except TypeError:
    pass
except:
    assert False, "Raised the wrong exception type"
else:
    assert False, "Didn't raise any exception"

(Dieser Code sollte in der Praxis zu einem allgemeineren Test abstrahiert werden).

31voto

Alice Purcell Punkte 12005

Try-except-else ist hervorragend geeignet für die Kombination von das EAFP-Muster mit duck-typing :

try:
  cs = x.cleanupSet
except AttributeError:
  pass
else:
  for v in cs:
    v.cleanup()

Sie denken vielleicht, dass dieser naive Code in Ordnung ist:

try:
  for v in x.cleanupSet:
    v.clenaup()
except AttributeError:
  pass

Dies ist eine großartige Möglichkeit, um versehentlich schwere Fehler in Ihrem Code zu verstecken. Ich habe dort einen Tippfehler gemacht, aber der AttributeError, der mich darauf aufmerksam machen würde, wird verschluckt. Schlimmer noch, was wäre, wenn ich es zwar richtig geschrieben hätte, aber der Cleanup-Methode gelegentlich ein Benutzertyp übergeben wurde, der ein falsch benanntes Attribut hatte, was dazu führte, dass sie auf halbem Weg scheiterte und eine Datei ungeschlossen ließ? Viel Glück bei der Fehlersuche in diesem Fall.

22voto

RoadieRich Punkte 5928

Ich finde es sehr nützlich, wenn man etwas aufräumen muss, auch wenn es eine Ausnahme gibt:

try:
    data = something_that_can_go_wrong()
except Exception as e: # yes, I know that's a bad way to do it...
    handle_exception(e)
else:
    do_stuff(data)
finally:
    clean_up()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X