Vermeidung von Windows-Backslash-Problemen mit Pythons Raw-Strings

Ich bin ein Unix-Typ, aber die Teilnehmer meiner Python-Kurse benutzen überwiegend Windows. Wenn wir über die Arbeit mit Dateien in Python sprechen, kommt es unweigerlich vor, dass jemand eine Datei mit dem vollständigen Pfad zur Datei öffnen möchte. Und am Ende schreiben sie dann so etwas wie das hier:

filename = 'c:\abc\def\ghi.txt'

Aber wenn meine Studenten versuchen, die Datei zu öffnen, stellen sie fest, dass Python ihnen eine Fehlermeldung gibt, die besagt, dass die Datei nicht existiert! Mit anderen Worten, sie schreiben:

for one_line in open(filename): print(one_line)

Was ist das Problem? Das scheint ein ziemlich normales Python zu sein, oder?

Erinnern Sie sich, dass Zeichenketten in Python normalerweise Zeichen enthalten. Diese Zeichen sind normalerweise druckbar, aber es gibt Fälle, in denen man ein Zeichen einfügen möchte, das nicht wirklich druckbar ist, wie z.B. ein Zeilenumbruch. Für solche Fälle enthält Python (wie viele Programmiersprachen) spezielle Codes, die das Sonderzeichen einfügen.

Das bekannteste Beispiel ist der Zeilenumbruch, auch bekannt als „\n“ oder ASCII 10. Wenn Sie einen Zeilenumbruch in Ihre Python-Zeichenkette einfügen wollen, dann können Sie dies mit ‚\n‘ in der Mitte tun. Beispiel:

s = 'abc\ndef\nghi'

Wenn wir die Zeichenkette ausdrucken, sehen wir:

>>> print(s)abcdefghi

Was aber, wenn Sie ein wörtliches ‚\n‘ in Ihrem Code ausgeben wollen? Das heißt, Sie wollen einen Backslash, gefolgt von einem „n“? Dann müssen Sie den Backslash verdoppeln: Das „\\“ in einer Zeichenkette ergibt ein einzelnes Backslash-Zeichen. Das folgende „n“ ist dann normal. Zum Beispiel:

s = 'abc\ndef\nghi'

Wenn wir sagen:

>>> print(s)abc\ndef\nghi

Es ist ziemlich bekannt, dass man sich vor dieser Übersetzung hüten muss, wenn man mit \n arbeitet. Aber bei welchen anderen Zeichen ist dies erforderlich? Es stellt sich heraus, dass es mehr sind, als viele Leute erwarten würden:

  • \a – Alarmglocke (ASCII 7)
  • \b – Rücktaste (ASCII
  • \f – Formfeed
  • \n – Zeilenumbruch
  • \r – Wagenrücklauf
  • \t – Tabulator
  • \v – vertikaler Tabulator
  • \ooo – Zeichen mit oktalem Wert ooo
  • \xhh – Zeichen mit hexadezimalem Wert hh
  • \N{name} – Unicode Zeichen {name}
  • \uxxxx – Unicode Zeichen mit 16-Bit-Hex-Wert xxxx
  • \Uxxxxxxxx – Unicode-Zeichen mit 32-Bit-Hex-Wert xxxxxxxx

Nach meiner Erfahrung, ist es äußerst unwahrscheinlich, dass Sie einige dieser Zeichen absichtlich verwenden. Ich meine, wann haben Sie das letzte Mal ein Formfeed-Zeichen gebraucht? Oder einen vertikalen Tabulator? Ich weiß – es war ungefähr an dem Tag, an dem Sie Ihren Dinosaurier zur Arbeit gefahren haben, nachdem Sie in Ihrem Garten einen Brunnen für Trinkwasser gegraben hatten.

Aber fast jedes Mal, wenn ich Python unterrichte – also jeden Tag – stößt jemand in meiner Klasse versehentlich auf eines dieser Zeichen. Das liegt daran, dass die Kombination der Backslashes, die von diesen Zeichen verwendet werden, und der Backslashes, die in Windows-Pfaden verwendet werden, zu unvermeidlichen und frustrierenden Fehlern führt.

Erinnern Sie sich an den Pfad, den ich am Anfang des Blogposts erwähnt habe und der so unschuldig erscheint?

filename = 'c:\abc\def\ghi.txt'

Er enthält ein „\a“-Zeichen. Das bedeutet, wenn wir ihn ausdrucken:

>>> print(filename)c:bc\def\ghi.txt

Siehst du? Das „\a“ ist verschwunden und durch ein Weckzeichen ersetzt. Wenn Sie Glück haben.

Was können wir also tun? Die Backslashes verdoppeln, natürlich. Sie brauchen nur diejenigen zu verdoppeln, die in Sonderzeichen umgewandelt werden, wie in der oben abgebildeten Tabelle angegeben: Aber kommen Sie, können Sie sich wirklich merken, dass „\f“ ein Sonderzeichen ist, „\g“ aber nicht? Wahrscheinlich nicht.

Daher lautet meine allgemeine Regel, und ich sage das auch meinen Studenten, dass sie die Backslashes in ihren Windows-Pfaden immer verdoppeln sollten. Mit anderen Worten:

>>> filename = 'c:\abc\def\ghi.txt'>>> print(filename)c:\abc\def\ghi.txt

Es funktioniert!

Aber halt: Niemand will sich wirklich durch seine Pfadnamen wühlen und jeden Backslash verdoppeln, oder? Natürlich nicht.

Da können die raw strings von Python helfen. Es gibt zwei Arten von Raw Strings:

  • What-you-see-is-what-you-get Strings
  • Automatisch verdoppelte Backslashes in Strings

Der Effekt ist in beiden Fällen derselbe: Alle Backslashes werden verdoppelt, so dass all diese lästigen und seltsamen Sonderzeichen verschwinden. Das ist großartig, wenn Sie mit Windows-Pfaden arbeiten.

Sie müssen nur ein „r“ vor die öffnenden Anführungszeichen (einfach oder doppelt) setzen:

>>> filename = r'c:\abc\def\ghi.txt'>>> print(filename)c:\abc\def\ghi.txt

Beachten Sie, dass eine „rohe Zeichenfolge“ nicht wirklich eine andere Art von Zeichenfolge ist. Es ist nur eine andere Art, eine Zeichenkette in Python einzugeben. Wenn Sie nachsehen, wird type(filename) immer noch „str“ sein, aber die Backslashes werden alle verdoppelt.

Unterste Zeile: Wenn Sie Windows verwenden, sollten Sie alle hart kodierten Pfadnamen als rohe Zeichenketten schreiben. Selbst wenn Sie ein Python-Experte sind, kann ich Ihnen aus Erfahrung sagen, dass Sie manchmal auf dieses Problem stoßen werden. Und selbst für die Besten unter uns kann es zeitaufwendig und frustrierend sein, das verirrte „\f“ in einer Zeichenkette zu finden.

PS: Ja, es stimmt, dass Windows-Benutzer dieses Problem umgehen können, indem sie Schrägstriche verwenden, wie wir Unix-Benutzer es tun. Aber meine Studenten finden, dass dies besonders seltsam aussieht, und deshalb sehe ich es nicht als Allzwecklösung an.

Ist Ihnen dieser Artikel gefallen? Schließen Sie sich mehr als 11.000 anderen Entwicklern an, die meinen kostenlosen, wöchentlichen Newsletter „Bessere Entwickler“ erhalten. Jeden Montag erhalten Sie einen Artikel wie diesen über Softwareentwicklung und Python:

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.