sys.argv als Bytes in Python 3k

8

Da Python 3k strikt zwischen Strings und Bytes unterscheidet, werden Befehlszeilenargumente im Array sys.argv als Strings dargestellt. Manchmal ist es notwendig, die Argumente als Bytes zu behandeln, z. wenn ein Pfad übergeben wird, der in keiner bestimmten Zeichencodierung in Unix sein muss.

Sehen wir uns ein Beispiel an. Ein kurzes Python 3k-Programm argv.py folgt:

%Vor%

Wenn es als python3.1 argv.py français ausgeführt wird, erzeugt es die erwartete Ausgabe:

  

français

     

b'bytes

Beachten Sie, dass das Argument français in meiner Gebietsschema-Codierung ist. Wenn wir das Argument jedoch in einer anderen Kodierung übergeben, erhalten wir einen Fehler: python3.1 argv.py 'echo français|iconv -t latin1'

%Vor%

Wie sollen wir binäre Daten über Befehlszeilenargumente an Python 3k übergeben? Ein Beispiel für die Verwendung ist die Übergabe eines Pfades an eine Datei eines Benutzers, der ein anderes Gebietsschema verwendet.

    
David 08.08.2011, 11:43
quelle

2 Antworten

8

Beachten Sie, dass der Fehler ein UnicodeEncodeError und nicht ein UnicodeDecodeError ist. Python behält die genauen Bytes bei, die über die Befehlszeile übergeben wurden (über den PEP 383 surrogateescape Error-Handler), aber diese Bytes sind nicht gültig UTF-8 und können daher nicht als solche zum Schreiben in die Konsole codiert werden.

>

Der beste Weg, um damit umzugehen, ist die Anwendung der Kenntnis der korrekten Kodierung auf Anwendungsebene, um das Befehlszeilenargument in der Anwendung neu zu interpretieren, wie im folgenden Beispielcode:

%Vor%

Der% code_% -Funktionsaufruf kehrt die Transformation um, die Python bei der Verarbeitung der Befehlszeilenargumente automatisch anwendet. Der Methodenaufruf os.fsencode führt dann die korrekte Konvertierung durch, um eine korrekt decodierte Zeichenfolge zu erhalten.

decode('latin-1') wurde in Python 3.2 hinzugefügt, um diese Art von Problem leichter zu lösen. Für Python 3.1 ist das äquivalente Konstrukt für os.fsencode os.fsencode(sys.argv[1])

Edit Feb 2013: aktualisiert für Python 3.2+ und um zu vermeiden, dass Python automatisch "UTF-8" als Befehlszeilen-Codierung erkennt

    
ncoghlan 16.08.2011 11:54
quelle
2

Sie können:

sys.argv[1].encode() oder, wenn Sie die Codierung kennen, verwenden Sie sie als Argument oder rufen Sie bytes(sys.argv[1], 'latin-1') auf.

Beide sollten Ihnen eine Byte-Darstellung der Unicode-Zeichenfolge geben.

Standardmäßig verwendet Python3 UTF-8.

    
JBernardo 09.08.2011 01:00
quelle

Tags und Links