Ich verwende argparse, um Argumente für meinen Python-Code einzulesen. Eine dieser Eingaben ist der Titel einer Datei [title], die Unicode-Zeichen enthalten kann. Ich habe 22少女時代22 als Testzeichenfolge verwendet.

Ich muss den Wert der Eingabe title in eine Datei schreiben, aber wenn ich versuche, die Zeichenfolge in UTF-8 zu konvertieren, wird immer ein Fehler ausgegeben:

UnicodeDecodeError: Der Codec 'ascii' kann das Byte 0x8f an Position 2 nicht dekodieren: Ordnungszahl nicht im Bereich (128)

Ich habe mich umgesehen und festgestellt, dass meine Zeichenfolge die Form u"foo" haben muss, um .encode() darauf aufzurufen.

Wenn ich type() für meine Eingabe von argparse ausführe, sehe ich:

<type 'str'>

Ich freue mich auf eine Antwort von:

<type 'unicode'>

Wie kann ich es in die richtige Form bringen?

Idee:

Ändern Sie argparse, um ein str aufzunehmen, speichern Sie es jedoch als Unicode-Zeichenfolge u"foo":

parser.add_argument(u'title', metavar='T', type=unicode, help='this will be unicode encoded.')

Dieser Ansatz funktioniert überhaupt nicht. Gedanken?

Bearbeiten 1:

Ein Beispielcode, bei dem title 22少女時代22 ist:

inputs = vars(parser.parse_args())
title = inputs["title"]
print type(title)
print type(u'foo')
title = title.encode('utf8') # This line throws the error
print title
5
Morrowind789 7 Okt. 2012 im 02:54

2 Antworten

Das Festlegen von type=unicode entspricht der Verwendung von unicode(arg), die standardmäßig mit ascii unter Python 2.X dekodiert wird. Wenn Sie von der Konsole aus ausführen, ist sys.stdin.encoding die für die Eingabe verwendete Codierung.

inputs = vars(parser.parse_args())
title = inputs["title"]
print type(title)
print type(u'foo')
title = title.decode(sys.stdin.encoding)
print title

Unabhängig von der Codierung unter Windows sollte die mbcs - Codierung funktionieren, die die aktuelle Codierung darstellt, die von Nicht-Unicode-Windows-Programmen verwendet wird. Dies scheint das zu sein, was argparse verwendet, da I sys.stdin.encoding die OEM -Konsolencodierung ist, die nicht immer mit der Windows-Codierung identisch ist. Unter US-Windows ist cp437 die OEM-Codierung der Konsole und cp1252 die Windows-Codierung:

import argparse
import codecs
parser = argparse.ArgumentParser()
parser.add_argument(u'title', metavar='T', type=str, help='this will be unicode encoded.')
opts = parser.parse_args()
title = opts.title.decode('mbcs')
with codecs.open('out.txt','w',encoding='utf-8-sig') as f:
    f.write(title)

out.txt sollte die ursprüngliche Eingabe im Editor anzeigen.

Die utf-8-sig -Codierung schreibt die sogenannte Byte Order Mark (BOM), die Windows am Anfang von UTF-8-Dateien mag. utf-8 kann verwendet werden, wenn dies nicht erwünscht ist, aber Notepad gefällt es.

4
Mark Tolonen 6 Okt. 2012 im 23:30

Das funktioniert also tatsächlich für mich:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument(u'title', metavar='T', type=str, help='this will be unicode encoded.')
opts = parser.parse_args()
print opts.title.decode('utf8')

Mein Terminalemulator (OS X Terminal.app) verwendet UTF-8. Wenn Ihr Terminal nicht für den UTF-8-Betrieb konfiguriert ist, funktioniert es nicht (und dann handelt es sich um ein Terminalproblem, nicht um ein Python-Problem).

2
nneonneo 6 Okt. 2012 im 23:01