Seltsame Dinge in Python: unsichtbare Zeichen!

Vorwort

  Heute möchte ich etwas sehr Seltsames mitteilen: Beim Schreiben von Code bin ich auf unsichtbare Zeichen gestoßen! ! !

1. Ursache

  Heute habe ich plötzlich eine Fehlermeldung erhalten, als ich pipreqsdie Bibliotheken verwendet habe, auf die ich zum Exportieren des Projekts angewiesen war:

pipreqs . --encoding=utf-8 --force

# 以下是报错信息
ERROR: Failed on file: ./build.py
Traceback (most recent call last):
  File "/usr/local/bin/pipreqs", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.8/dist-packages/pipreqs/pipreqs.py", line 528, in main
    init(args)
  File "/usr/local/lib/python3.8/dist-packages/pipreqs/pipreqs.py", line 455, in init
    candidates = get_all_imports(input_path,
  File "/usr/local/lib/python3.8/dist-packages/pipreqs/pipreqs.py", line 131, in get_all_imports
    raise exc
  File "/usr/local/lib/python3.8/dist-packages/pipreqs/pipreqs.py", line 117, in get_all_imports
    tree = ast.parse(contents)
  File "/usr/lib/python3.8/ast.py", line 47, in parse
    return compile(source, filename, mode, flags,
  File "<unknown>", line 1
    # -*- coding:utf-8 -*-
    ^
SyntaxError: invalid character in identifier

  Als ich direkt kam SyntaxError, #stellte sich heraus, dass es sich um einen ungültigen Charakter handelte. Der Charakter #bedeutete, dass er sehr unschuldig war, und die betroffene Person war sehr schockiert! ! ! Ist das nicht ein tolles Zeichen dafür, die Welt zu verlassen, und ein toller Witz darüber, in die Welt hineinzuschlüpfen? ? ? Dies ist nur eine Zeile Codekommentar, wie könnte das schief gehen!

Fügen Sie hier eine Bildbeschreibung ein

2. Untersuchung

  Als ich zum ersten Mal auf so etwas Böses stieß, überprüfte ich den pipreqsQuellcode. Der Code war sehr einfach, also habe ich den Teil extrahiert, der den Fehler gemeldet hat:

# pipreqs/pipreqs.py line 112
for file_name in files:
    file_name = os.path.join(root, file_name)
    with open(file_name, "r", encoding=encoding) as f:
        contents = f.read()
    try:
        tree = ast.parse(contents)	# 在这里报错了
        for node in ast.walk(tree):
            if isinstance(node, ast.Import):
                for subnode in node.names:
                    raw_imports.add(subnode.name)
            elif isinstance(node, ast.ImportFrom):
                raw_imports.add(node.module)
    except Exception as exc:
    	...

  Die Bedeutung ist ebenfalls leicht zu verstehen: Lesen Sie alle Dateien pipreqsim aktuellen Projekt und führen Sie dann mithilfe der Bibliothek eine Syntaxanalyse durch, um den Bibliotheksnamen zu erhalten, von dem die Datei abhängt. Da dieser Teil einen Fehler meldete, habe ich ihn direkt herausgenommen. Zu diesem Zeitpunkt hatte ich den starken Verdacht, dass etwas Ernstes vorlag !pythonastpythonastbug

3. Hohe Energie

  Um zu bestätigen, dass astbeim Parsen der Datei ein Fehler aufgetreten ist, habe ich alle pythonDateien im aktuellen Projekt einzeln getestet. Die Entwicklung hat jedoch meine Erwartungen übertroffen: Die zweite Datei (process_data.py)konnte analysiert werden!
  Ich habe mir diese Datei angesehen und festgestellt, dass sie am Anfang denselben Kommentar enthält, aber es wurde kein Fehler gemeldet. Gibt es ein Problem mit der Kodierung? Ich habe es geöffnet Pycharmund einen Blick darauf geworfen, und es gab kein Problem:

Fügen Sie hier eine Bildbeschreibung ein
  Das war zu seltsam, also habe ich es debugnoch einmal überprüft und mir den Inhalt der Datei angesehen, um sicherzustellen, dass nichts falsch war:

Fügen Sie hier eine Bildbeschreibung ein
  Ich konnte es nicht herausfinden, also fragte ich ChatGPT:

Fügen Sie hier eine Bildbeschreibung ein
  Es wurden vier Zweifelspunkte vergeben, die grundsätzlich nacheinander beseitigt wurden. python 3.8Die Dateien waren utf-8kodiert, es gab keine Grammatikfehler und es gab keine Probleme mit den Kommentaren. Aber eines verstehe ich nicht: unsichtbare Sonderzeichen?
  Unsichtbar? Da es sich um ein Zeichen handelt, muss es einen Platz haben, auch wenn es nicht sichtbar ist. Dann passierte das Seltsamste:

Fügen Sie hier eine Bildbeschreibung ein
  Es gibt wirklich ein Nullzeichen an der ersten Position, dies. . . Können leere Zeichen trotzdem Platz beanspruchen?
  Nachdem ich es gedruckt hatte ASCII, stellte ich fest, dass der Wert lautete 65279und das leere Zeichen tatsächlich ASCIIeinen Wert hatte. Ich hatte plötzlich das Gefühl, dass dieses Problem nicht einfach war. Ist es wirklich unsichtbar?

Fügen Sie hier eine Bildbeschreibung ein

4. Beseitigen Sie Verwirrung

  Baidu hat einen Blick darauf geworfen und festgestellt, dass ASCIIder Wert 65279durch die in der Datei verwendete Codierung verursacht wird UTF-8 BOM. Dies ist Windowsdie Standardcodierungsmethode beim Erstellen von Dateien in der Umgebung. Ich habe mir das auch speziell angesehen und festgestellt, dass es sich tatsächlich um Folgendes handelt:

Fügen Sie hier eine Bildbeschreibung ein
  Diese Einstellung gibt es auch in Pycharm. Standardmäßig Pycharmwird die Codierung beim Erstellen neuer Dateien in verwendet UTF-8 with NO BOM, was oft gesagt wird UTF-8. Der Grund, warum asteinige Bibliotheken Dateien normal analysieren können und andere nicht, liegt darin, dass einige Dateien möglicherweise nicht in PycharmErstellt in sind, was dazu führte zu dieser seltsamen Zeit, die passiert. Gleichzeitig habe ich die Datei im Binärmodus gelesen und festgestellt, dass die ersten drei Bytes \xEF\xBB\xBF, die UTF-8 BOMbeim Codieren automatisch hinzugefügt wurden.

py_file = './build.py'
with open(py_file, 'r', encoding='utf-8') as f:
    contents = f.read()
    if ord(contents[0]) == 65279:
        print('UTF-8 BOM')

with open(py_file, 'rb') as f:
    contents = f.read(3)
    if contents == b'\xEF\xBB\xBF':
        print('UTF-8 BOM')

# UTF-8 BOM
# UTF-8 BOM

  Also habe ich die Dateikodierung von auf UTF-8 BOMgeändert UTF-8und das Problem war gelöst!

Fügen Sie hier eine Bildbeschreibung ein


  Folgen Sie dem öffentlichen WeChat-Konto: 夏小悠um weitere Artikel, Artikel PPTund andere Informationen zu erhalten ^_^

Supongo que te gusta

Origin blog.csdn.net/qq_42730750/article/details/132249961
Recomendado
Clasificación