Python打印在不同服务器上的工作方式不同

Python打印在不同服务器上的工作方式不同,python,unicode,twisted,Python,Unicode,Twisted,当我尝试在我的开发服务器上打印unicode字符串时,它工作正常,但生产服务器引发异常 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(

当我尝试在我的开发服务器上打印unicode字符串时,它工作正常,但生产服务器引发异常

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)
实际上,它是一个扭曲的应用程序,并打印到日志文件

字符串的repr()是相同的。语言环境设置为en_US.UTF-8


是否有任何配置需要检查,以使其在两台服务器上工作相同?

打印Unicode字符串取决于
sys.stdout
(进程的标准输出)具有正确的
.encoding
属性,Python可以使用该属性将unicode字符串编码为字节字符串,以执行所需的打印——该设置取决于操作系统的设置方式、标准输出指向的位置等等

如果没有这样的属性,则使用默认编码的
ascii
,如您所见,它通常不会提供所需的结果;-)

您可以检查
getattr(sys.stdout,'encoding',None)
以查看编码是否存在(如果存在,您可以祈祷它是正确的……或者,尝试一些特定于平台的技巧来猜测要检查的正确系统编码;-)。如果不是,一般来说,没有可靠或跨平台的方法来猜测它可能是什么。您可以尝试
'utf8'
,这是一种在很多情况下都能工作的通用编码(当然比
ascii
更有效;-),但它确实是一种轮盘赌

为了提高可靠性,您的程序应该有自己的配置文件来告诉它要使用什么输出编码(如果没有另外指定,可以使用
'utf8'
作为默认值)

为了可移植性,最好执行自己的编码,也就是说,不需要

而是

print someunicode.encode(thecodec)
事实上,如果你宁愿有不完整的输出也不要崩溃

print someunicode.encode(thecodec, 'ignore')
(只跳过不可编码的字符),或者,通常更好

print someunicode.encode(thecodec, 'replace')

(对不可编码的字符使用问号占位符)。

Twisted的内置日志观察程序不支持Unicode。有关为此添加支持的进度,请参阅,或者查看您可以做些什么来提供帮助


在解决#989问题并在部署应用程序的Twisted版本中修复之前,不要记录unicode。只有log
str

服务器运行的是什么OSs和Python版本?Ubuntu 10.04 Server Bot我认为值得一提的是,在UNIX系统上,sys.stdout.encoding是基于
LANG
LC\u ALL
LC\u CTYPE
环境变量设置的,并且仅当sys.stdout连接到终端时才设置。不幸的是,当您将输出重定向到文件或其他程序时,相同的工作打印可能会中断。这使得对unicode进行显式编码变得更为重要。它不起作用,因为打印输出会写入日志。我更新了我的问题。谢谢你的回复。两台服务器上的语言环境都设置为en_US.UTF-8。我随机尝试了不同的编码,mystring.decode('utf8')似乎可以在生产服务器上工作。但这给开发人员带来了一个例外:@Alex从未遇到过这个问题,但答案很好。我相信这些信息在将来会派上用场:)@Gregory,所以,在开发中,使用
mystring.encode(sys.stdout.encodeing)
(绝对不是
.decode
,就像你说的那样,这简直太疯狂了,在任何情况下都不会起作用——你想用这种方式实现什么?!),
'utf8'
在产品上。
getattr(sys.stdout,'encoding','utf8')
将在任何一个系统上为您提供正确的编解码器名称(并尝试使用
'replace'
,以增加安全性!)。如果我需要编码或解码或其他什么的话也可以。但是生产服务器需要进行解码('utf8'),而开发服务器不允许这样做。
print someunicode.encode(thecodec, 'replace')