[PYTHON] Rückgabewert von quit () - Gibt es etwas, das von der "Funktion, die alles beendet" zurückgegeben wird?

Dank Chun und Cocoatomo für ihre Antworten und Referenzartikel in der Discord-Community haben wir große Fortschritte beim Lösen und Überzeugen gemacht. Vielen Dank. Ich möchte diese Gelegenheit nutzen, um Ihnen zu danken.

Der Anfang der Sache

Als ich [diesen Artikel] las (https://qiita.com/ksato9700/items/44caf7bf0329fb987499), fand ich den Code, an dem ich interessiert war, in den Kommentaren des Artikels.

x = f"{quit()}"
while True:
    print("hello")

Wie der Artikelkommentar-Autor sagte, wird "Hallo" nicht ausgegeben und endet, wenn ich diesen Code ausführe.

Ich fühlte mich hier etwas unwohl und habe es nachgeschlagen.

In Bezug auf F-String gemäß dem offiziellen Dokument,

Formatiertes String-Literal oder F-String ist ein String-Literal mit dem Präfix 'f'or'F'. Diese Zeichenfolgen können Ersatzfelder enthalten, bei denen es sich um Ausdrücke handelt, die durch gewellte Klammern {} getrennt sind. Formatierte String-Literale werden zur Laufzeit als Ausdrücke ausgewertet, während andere String-Literale immer konstant sind und sich nicht ändern.

Und das. Das heißt, wenn Sie eine Funktion in {} einfügen, wird ihr Rückgabewert durch ein Feld ersetzt. Formatiert eine Zeichenfolge, unabhängig davon, ob der Rückgabewert der Funktion int, list oder dict ist. Am Ende ist F-String eine ziemlich mächtige weiße Sache, die sogar NoneType in einen String "None" verwandelt.

** Was die quit () -Funktion, die diesen mächtigen F-String gebrochen hat, zurückgegeben hat **

Dies war meine erste Frage.

Ansatz 1 Siehe Typ ()

Zuerst dachte ich, ich könnte den Hinweis sehen, wenn ich wüsste, welche Art von "Typ" quit () zurückgibt, also habe ich den folgenden Code ausgeführt.

>>> print(type(quit()))

C:\work>

Regentag ** Python Interpreter selbst ist fertig **

Wie oben erwähnt, wird, wenn der Rückgabewert NoneType ist, die Zeichenfolge "None" ausgegeben, wenn Sie sie in eine f-Zeichenfolge einfügen. Daher habe ich erwartet, dass der Rückgabewert von quit () nicht NoneType ist. Anstatt keine Ergebnisse zu erhalten, wird der gesamte Interpreter gelöscht ...

Ansatz 2 Siehe Teil Funktionsdefinition

Selbst wenn Sie den Typ nicht erhalten können, können Sie sehen, was Sie tun, indem Sie sich die Quelle der eigentlichen Funktion quit () ansehen. Dachte ich und warf einen Blick auf das Beenden im eingebauten.

builtin.pyi


def quit(code: object = ...) -> NoReturn: ...

** Es gibt überhaupt keine Rückkehr, und das mysteriöse No Return behauptet, dass es keine Unterlassung oder ein Fehler ist **

Ich hielt es für selbstverständlich, dass die Funktion eine Rückkehr hatte, also war ich bereits erschöpft und beschloss, eine Frage in der Discord-Community zu stellen.

Ansatz 3 hat mich gelehrt

Ich konnte eine Antwort von der Community bekommen. Ich werde es zitieren.

sys.exit (), exit (), quit () löst eine SystemExit-Ausnahme aus Referenz: https://docs.python.org/3/library/constants.html

  1. In {} auswerten
  2. Eine Ausnahme auslösen Fazit: Es wird nicht nach der zweiten Zeile ausgeführt Ich denke es ist wie Ich denke, NoReturn tippt. NoReturn Referenz: https://docs.python.org/3/library/typing.html Wenn Sie den Rückgabewert der Funktion nicht angeben (wenn Sie nicht return verwenden), wird None automatisch zurückgegeben, sodass es sich nicht um No Return handelt. def Funktionsname () -> Keine: pass

Mit anderen Worten, quit (), sys.exit (), exit () usw. sind ** Funktionen, die immer Ausnahmen geben **.

Ausnahmeidentität und keine Rückgabe

Was die SystemExit-Ausnahme betrifft, die Sie mir mitgeteilt haben, können Sie die Ausnahme nicht abfangen, selbst wenn Sie quit () oder sys.exit () normal ausführen, und es wird kein Traceback angezeigt. Dies liegt daran, dass SystemExit-Ausnahmen keine ** Ausnahmen sind, sondern direkt BaseException erben, die Hauptklasse, die sie erben. Es scheint, dass die Ausnahmen, die normal abgefangen werden können, KeyError und TypeError, von der Exception-Klasse geerbt werden und SystemExit nicht darin enthalten ist.

Informationen zur BaseException

** BaseException ist das Meisterwerk aller Python-Ausnahmen **, und es gibt nur vier Ausnahmeklassen, die direkt davon erben: SystemExit, GeneratorExit, KeyboardInterrupt und Exception.

Der Tastatur-Interrupt ist "Strg + C". Ausnahme ist die Basisklasse für alle anderen Ausnahmen, und benutzerdefinierte Ausnahmen sollten ebenfalls darauf basieren. Wenn Sie Code mit einem Fehler schreiben, wird von Traceback derjenige erfasst und ausgegeben, der diese Ausnahmeklasse erbt, und die Ausnahme, die BaseException direkt erbt, wird nicht abgefangen.

Verwenden Sie das Traceback-Modul, um eine BaseException abzufangen. Lassen Sie uns die SystemExit-Ausnahme abfangen, die in der ersten Zeile des Eröffnungscodes erwartet wird.

import traceback
try:
    x = f"{quit()}"
    print(x)
except BaseException: #BaseException wird nur für den Fall angegeben, jedoch nur mit Ausnahme:Aber sie werden es abholen
    print(traceback.format_exc())

Das Ergebnis ist wie folgt

python


Traceback (most recent call last):
  File "c:/work/catchBaseException.py", line 3, in <module>
    x = f"{quit()}"
  File "C:\Python\Python37\lib\_sitebuiltins.py", line 26, in __call__
    raise SystemExit(code)
SystemExit: None

** Ich konnte den System-Exit von BaseException sicher abfangen **

Über keine Rückkehr

Das ist nicht so schwierig, es ist ein Typ-Hinweis, eine Darstellung des erwarteten Ergebnisses.

Ursprünglich scheint die Funktion implizit "return None" zu sein, wenn return nicht angegeben ist. Zum Beispiel der folgende Code

python


def no_return():
    pass

x = no_return()
print(type(x))


<class 'NoneType'>

Weit entfernt von return None wird return selbst nicht in der Funktion no_return () festgelegt, aber der Rückgabetyp ist NoneType. Mit anderen Worten, die Funktion no_return impliziert implizit "Keine zurückgeben". Dies ist jedoch der Fall, wenn die Funktion normal bis zum Ende ausgeführt wird und keine Rückgabe erfolgt.

** quit () und sys.exit (), die eine Ausnahme ausspucken, geben nicht einmal implizit None zurück **

Der Typhinweis einer Funktion beschreibt den erwarteten Wert des Typs, den die Funktion zurückgibt. Das erwartete Ergebnis dieser Funktionen, das selbst None nicht zurückgibt, ist jedoch, dass der Inhalt des Typhinweises "NoReturn" lautet. Es scheint so zu sein.

Zusammenfassung

--quit (), sys.exit () lösen die Ausnahme SystemExit aus --SystemExit ist eine spezielle Version, die die Hauptausnahmeklasse BaseException direkt erbt.

Referenzlink

Offizielle Dokumentation https://docs.python.org/ja/3/library/constants.html https://docs.python.org/ja/3/library/exceptions.html#SystemExit https://docs.python.org/ja/3/library/typing.html#typing.NoReturn Qiita https://qiita.com/ksato9700/items/44caf7bf0329fb987499 https://qiita.com/hayata-yamamoto/items/259238dad038b5bee51c Pythonjp Offizielle Zwietracht https://www.python.jp/pages/pythonjp_discord.html

Recommended Posts

Rückgabewert von quit () - Gibt es etwas, das von der "Funktion, die alles beendet" zurückgegeben wird?
Die Geschichte, dass der Rückgabewert von tape.gradient () None war
Über den Rückgabewert von pthread_mutex_init ()
Über den Rückgabewert des Histogramms.
Ermitteln Sie den Mindestwert der Funktion mithilfe der Partikelgruppenoptimierungsmethode (PSO).
Achten Sie auf den Rückgabewert von __len__
Der Wert von pyTorch torch.var () wird nicht verteilt
Der Rückgabewert (Generator) einer Funktion, die endlich und Ausbeute kombiniert, darf nicht direkt an next übergeben werden
Suchen Sie nach dem Wert der Instanz in der Liste
[Python of Hikari-] Kapitel 06-02 Funktion (Argument und Rückgabewert 1)
Um den Ort, an dem der Wert von Errbot gespeichert ist
#Eine Funktion, die den Zeichencode einer Zeichenfolge zurückgibt
Die Kopiermethode von pandas.DataFrame ist standardmäßig Deep Copy
[Linux] [C / C ++] So ermitteln Sie den Wert der Rücksprungadresse einer Funktion und den Funktionsnamen des Aufrufers
Der Wert von meta beim Angeben einer Funktion ohne Rückgabewert mit Dask dataframe gilt
Der Rückgabewert von len oder unichr kann sich ändern, je nachdem, ob es sich um UCS-2 oder UCS-4 handelt.