2010-09-18 2 views
6

Wenn ich versuche, eine Unicode-Zeichenfolge auf meinem Dev-Server zu drucken, funktioniert es korrekt, aber Produktionsserver löst Ausnahme aus.Python-Druck funktioniert auf verschiedenen Servern unterschiedlich

File "/home/user/twistedapp/server.py", line 97, in stringReceived 
    print "sent:" + json 
File "/usr/lib/python2.6/dist-packages/twisted/python/log.py", line 555, in write 
    d = (self.buf + data).split('\n') 
exceptions.UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 28: ordinal not in range(128) 

Eigentlich ist es Anwendung verdreht und drucken Sie nach vorne zu Protokolldatei.

repr() von Strings sind gleich. Gebietsschema auf en_US.UTF-8 festgelegt.

Gibt es irgendwelche Konfigurationen, die ich überprüfen muss, damit es auf beiden Servern gleich funktioniert?

+1

Welche Betriebssysteme und Python-Versionen laufen auf den Servern? – Puddingfox

+0

Ubuntu 10.04 Server sowohl – Soid

+0

und Python 2.6.5 – Soid

Antwort

1

Unicode wird von den integrierten Protokollbeobachtern von Twisted nicht unterstützt. Sehen Sie http://twistedmatrix.com/trac/ticket/989 für den Fortschritt beim Hinzufügen von Unterstützung für dieses oder um zu sehen, was Sie tun können, um zu helfen.

Bis # 989 behoben ist und das Update in einer Twisted-Version ist, auf der Ihre Anwendung bereitgestellt wird, melden Sie Unicode nicht an. Loggen Sie nur str ein.

+0

Warum kann es auf den verschiedenen Servern anders funktionieren? – Soid

+0

Es wäre in Ordnung, wenn ich codieren oder decodieren müsste oder so. Aber der Produktionsserver muss dekodieren ('utf8') und der Dev-Server erlaubt das nicht. – Soid

7

print ing von Unicode-Strings beruht auf sys.stdout (die Standardausgabe des Prozesses) ein korrektes .encoding Attribut, dass Python den Unicode-String in einen Byte-String kodieren, kann Sie den erforderlichen Druck auszuführen - und diese Einstellung ist abhängig von der Art und Weise das OS wird eingerichtet, wohin die Standardausgabe geleitet wird und so weiter.

Wenn es kein solches Attribut gibt, wird der voreingestellte Code ascii verwendet, und wie Sie gesehen haben, liefert es oft nicht die gewünschten Ergebnisse ;-).

Sie können überprüfen getattr(sys.stdout, 'encoding', None), um zu sehen, ob die Codierung dort ist (wenn es ist, können Sie nur die Daumen drücken, dass es korrekt ist ... oder, vielleicht, versuchen Sie einige stark plattformspezifische Trick auf das richtige System zu erraten Kodierung zu überprüfen ;-). Wenn dies nicht der Fall ist, gibt es im Allgemeinen keine verlässliche oder plattformübergreifende Möglichkeit zu erraten, was es sein könnte. Sie könnte versuchen 'utf8', die universelle Codierung, die in vielen Fällen funktioniert (sicherlich mehr als ascii tut ;-), aber es ist wirklich eine Drehung des Roulette-Rads.

Für mehr Zuverlässigkeit sollte Ihr Programm eine eigene Konfigurationsdatei haben, um zu sagen, welche Ausgabecodierung verwendet werden soll (vielleicht mit 'utf8' nur als Standard, wenn nicht anders angegeben).

Es ist auch besser, für die Portabilität, Ihre eigene Codierung durchzuführen, das heißt, nicht

print someunicode 

sondern

print someunicode.encode(thecodec) 

und tatsächlich, wenn Sie eher unvollständig ausgegeben haben würden als ein Crash,

print someunicode.encode(thecodec, 'ignore') 

(die einfach überspringt n on-kodierbaren Zeichen), oder, in der Regel besser,

print someunicode.encode(thecodec, 'replace') 

(das Fragezeichen-Platzhalter für uncodierbarer Zeichen verwendet).

+2

Ich denke, es ist erwähnenswert, dass auf UNIX-Systemen sys.stdout.Die Codierung wird basierend auf den Umgebungsvariablen 'LANG',' LC_ALL' und 'LC_CTYPE' festgelegt, und sie wird * nur * gesetzt, wenn sys.stdout mit einem Terminal verbunden ist. Die gleichen funktionierenden Drucke können leider brechen, wenn Sie die Ausgabe in eine Datei oder ein anderes Programm umleiten. Dies macht es noch wichtiger, Ihren Unicode explizit zu codieren. –

+0

@Thomas, ja, absolut, ausgezeichneter Punkt! –

+0

Es funktioniert nicht, weil die Ausgabe von Protokollen zu Protokollen führt. Ich habe meine Frage aktualisiert. Vielen Dank für Ihre Antwort. Das Gebietsschema wurde auf den beiden Servern auf en_US.UTF-8 gesetzt. – Soid