Seltsame Python-Fehlermeldung - Wird dieser Code wirklich ausgeführt?

Seltsame Fehlermeldung, was passiert?

In einem Verzeichnis auf einem Computer habe ich "eval (" 1/0 ")" in interaktivem Python (CPython) eingegeben.

Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> eval("1/0")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Soll ich bald ins Bett gehen?
  File "<string>", line 1, in <module>
Es ist schon die Grenze, oder?
ZeroDivisionError: division by zero

Ich sehe einen Laufzeitfehler mit Nullteilung, der wie erwartet ist. Aber, „Warum gehst du nicht bald ins Bett?" „Es ist schon die Grenze." Was ist das?

Python auf diesem Computer wurde nicht geändert, ebenso wie Standardbibliotheken. Es wurde kein Programm geschrieben, das dieses Phänomen verursacht. Was könnte die Ursache sein?

Wenn beim Ausführen der Quelldatei ein Fehler auftritt, wird der entsprechende Code angezeigt

Entfernen Sie sich mit seltsamen Meldungen vom Computer und überprüfen Sie die Art des Tracebacks, der angezeigt wird, wenn ein Fehler auftritt. Versuchen Sie zunächst, die Quelldatei "hello.py" auszuführen, die eine Nullteilung verursacht.

hello.py


print(1/0)
$ python3 hello.py
Traceback (most recent call last):
  File "hello.py", line 1, in <module>
    print(1/0)
ZeroDivisionError: division by zero

Traceback zeigt, dass der Fehler in der Zeile "print (1/0)" aufgetreten ist. Dies ist das erwartete Verhalten.

Der Code des Fehlerteils wird erhalten, nachdem der Fehler aufgetreten ist

Wie oben gezeigt, ist es praktisch, den Quellcode zu sehen, der den Fehler in Traceback verursacht hat. Da Python den Quellcode jedoch in Bytecode konvertiert und dann ausführt, enthält es den Quellcode während der Ausführung nicht. Muss. Was ist los. Tatsächlich liest Python den Quellcode erneut, nachdem ein Laufzeitfehler aufgetreten ist, und ruft den Code in diesem Teil ab. Um dies zu bestätigen, habe ich hello2.py erstellt, indem ich eine Zeile über hello.py eingefügt habe.

hello2.py


input("Please input> ")
print(1/0)

Warten Sie auf die Eingabe mit "Eingabe", bevor die Nullteilung durchgeführt wird. Während dieser Zeit werde ich versuchen, den Quellcode von hello2.py selbst mit einem Editor neu zu schreiben. Starten Sie zuerst die Ausführung und warten Sie auf die Eingabe.

$ python3 hello2.py 
Please input> 

Schreiben Sie die zweite Zeile mit dem entsprechenden Text neu.

hello2.py (nach dem Umschreiben)


input("Please input> ")
Bist du müde?

Geben Sie dem Prozess, der auf die Eingabe wartet, die entsprechende Eingabe und fahren Sie mit dem Prozess fort.

$ python3 hello2.py 
Please input> 123[Enter]
Traceback (most recent call last):
  File "hello2.py", line 2, in <module>
Bist du müde?
ZeroDivisionError: division by zero

Der Nullteilungsfehler, der mit dem Code "print (1/0)" hätte auftreten sollen, aber Traceback zeigte den umgeschriebenen Text "Sind Sie müde?" An. Sie können sehen, dass der Quellcode nach dem Auftreten des Fehlers geladen wurde.

Wenn keine Quelldatei vorhanden ist, wird der Code des Fehlerteils nicht angezeigt

Was aber, wenn bei der Standardeingabe oder der Ausführung von Zeichenfolgen ein Fehler auftritt? Der Code wird nicht in einer Datei gespeichert, sodass nach dem Auftreten des Fehlers nichts mehr zu lesen ist. Geben wir Python die Standardeingabe "hello.py".

$ python3 < hello.py
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

Es wird angezeigt, dass es sich um die erste Zeile von handelt, der tatsächliche Fehlercode wird jedoch nicht angezeigt. Was ist, wenn Sie den Code als Befehlszeilenargument angeben?

$ python3 -c 'print(1/0)'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ZeroDivisionError: division by zero

In ähnlicher Weise wird angezeigt, dass es sich um die erste Zeile von "" handelt, der Code für den Fehler wird jedoch nicht angezeigt. Unabhängig davon, ob es sich um "" oder "" handelt, ist es nicht vorhanden, sodass Sie den Quellcode nicht erhalten können.

Was sind und ?

Im obigen Traceback gab es Hinweise wie "Datei" "und" Datei "". Was ist das? In Dokumentation zur Kompilierungsfunktion

Dateiname Das Argument muss die Datei angeben, aus der der Code gelesen wird, und einen erkennbaren Wert übergeben, es sei denn, er wird aus der Datei gelesen ("" wird häufig verwendet. Masu).

Es gibt. Wenn keine Quelldatei vorhanden ist, wird die Zeichenfolge, die den Ursprung des Quellcodes angibt, als "Dateiname" festgelegt. Wenn Python beim Ausführen des Bytecodes auf einen Fehler stößt, vertraut es dem hier angegebenen "Dateinamen", um einen Traceback zu erstellen. Da Dateien wie "" und "" nicht vorhanden sind, kann in diesen Fällen der Code, der den Fehlerort angibt, nicht abgerufen werden und dort wird nichts angezeigt.

Was ist, wenn es eine Datei gibt, die nicht vorhanden sein sollte?

Aber gibt es absolut keine Dateien wie "" oder ""? Was wäre, wenn es so wäre? Diese Dateien werden in einem bestimmten Verzeichnis auf einem bestimmten Computer vorbereitet, der zu Beginn eingeführt wurde.

$ ls
<stdin>  <string>
$ cat '<stdin>'
Soll ich bald ins Bett gehen?
$ cat '<string>'
Es ist schon die Grenze, oder?

Da die Eingabe in den interaktiven Modus von Python über die Standardeingabe erfolgt, lautet der im Bytecode festgelegte "Dateiname" "".

>>> eval("1/0")

Zusätzlich ruft der Code die Funktion "eval" auf, die die Zeichenfolge in Bytecode kompiliert. Der "Dateiname" dieses Bytecodes lautet "". Wenn ein Fehler auftritt, vertraut Python diesen "Dateinamen" und erstellt einen Traceback, sodass die erste Zeile jeder vorbereiteten Datei angezeigt wird.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Soll ich bald ins Bett gehen?
  File "<string>", line 1, in <module>
Es ist schon die Grenze, oder?
ZeroDivisionError: division by zero

Dies ist die Ursache für das seltsame Phänomen. Zu diesem Zeitpunkt scheint die Quelldatei von sys.path durchsucht zu werden, also<stdin>und< Dies passiert, wenn sich string>in einem Verzeichnis befindet, das in sys.path enthalten ist.

Referenz

Es gab eine seltsame Fehlermeldung auf Twitter eingeführt. Informationen zum Bytecode finden Sie in der Dokumentation zum dis -Modul.

Recommended Posts

Seltsame Python-Fehlermeldung - Wird dieser Code wirklich ausgeführt?
[Python] tkinter Code, der wahrscheinlich wiederverwendet wird
[Python] Pandas Code, der wahrscheinlich wiederverwendet wird
Dieser Python-Code hat keine Klassen ...
Der heutige Python-Fehler: Das Bild ist leer
Python-Code, der DNA-Sequenzen ergänzt Welche Methode ist schneller?
Importfehler, obwohl ich Python installiert habe
Python-Code, der zusammenhängende Leerzeichen in einem entfernt