2016-08-24 3 views
1

Ich habe ein Problem, wo, wenn ich ein Skript ausführen, die das Einlesen von Daten aus einer Datei, die Unicode-Codepunkte enthält, alles funktioniert. Aber wenn es über eine andere Anwendung ausgeführt wird, wird es erhöht die folgenden Fehler:UnicodeDecodeError On Unicode-Datei Lesen

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128)

ich den exakt gleichen Code bin Ausführung genau die gleiche Datendatei. Eine Probe Datei, die das Problem repliziert ist wie folgt:

¥ Α © § 

ich diesen sample.txt

Ein sehr einfaches Python-Skript in einfach lesen genannt und den Dateiinhalt drucken:

with open("sample.txt") as f: 
    for line in f: 
     print(line) 

print("Done") 

Diese ausführt fein von der Kommandozeile; die Ausführung über Apache/CGI schlägt mit dem obigen Fehler fehl.

Antwort

1

Ein Hinweis auf das Problem kam von der Dokumentation der open Funktion:

In text mode, if encoding is not specified the encoding used is platform dependent: locale.getpreferredencoding(False) is called to get the current locale encoding. [Link]

Plattform vorgeschlagen Umgebungsvariablen abhängig. Also habe ich untersucht, welche Umgebungsvariablen für meine Shell gesetzt wurden, und LANG auf en_US.UTF-8 gesetzt. Dumping der Umgebungsvariablen von Apache festgestellt, dass LANG fehlte.

Offensichtlich, wenn das Gebietsschema nicht ermittelt werden kann, verwendet Python ASCII als Standardcodierung. Daher wurde der Fehler festgestellt, wenn die Ordinalzahl für ASCII außerhalb des zulässigen Bereichs lag.

Um das zu beheben, setze ich diese Umgebungsvariable in meinem CGI-Skript. Wenn die Umgebungsvariablen irgendwie von einem Benutzer-Shell fehlen, kann es über normale Verfahren eingestellt werden, oder einfach nur von:

export LANG=en_US.UTF-8 

oder was auch immer bevorzugte Codierung erwünscht ist.

Beachten Sie, dass das Problem wahrscheinlich viel auffälliger ist, wenn das Gebietsschema in einer Benutzer-Shell fehlt, da Texteditoren wie vi keine Zeichen ohne es anzeigen. Es war wesentlich subtiler, wenn nur ein Problem von Apache (oder einer anderen Anwendung) aufgerufen wurde.