当我尝试在我的开发服务器上打印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。
我需要检查哪些配置才能使它在两台服务器上都能正常工作?
答案 0 :(得分:7)
print
Unicode字符串依赖于sys.stdout
(进程的标准输出)具有正确的.encoding
属性,Python可以使用该属性将unicode字符串编码为字节字符串以执行所需的打印 - 该设置取决于操作系统的设置方式,标准输出的指向,等等。
如果没有这样的属性,则使用默认编码ascii
,正如您所见,它通常无法提供所需的结果; - )。
您可以检查getattr(sys.stdout, 'encoding', None)
以查看编码是否存在(如果存在,您可以保持手指交叉,这是正确的......或者,也许,尝试一些特定于平台的技巧来猜测正确的系统编码检查;-)。如果不是这样,一般来说,没有可靠的或跨平台的方式来猜测它可能是什么。您可以尝试'utf8'
,这种通用编码在很多情况下都有效(肯定比ascii
更多;-),但它实际上是轮盘赌的旋转。
为了获得更高的可靠性,您的程序应该有自己的配置文件来告诉它使用哪种输出编码(如果没有另外指定,可以使用'utf8'
作为默认值。)
为便于携带,执行自己的编码也更好,即不
print someunicode
而是
print someunicode.encode(thecodec)
实际上,如果您的输出不完整而不是崩溃,
print someunicode.encode(thecodec, 'ignore')
(只是跳过不可编码的字符),或者,通常更好,
print someunicode.encode(thecodec, 'replace')
(对不可编码的字符使用问号占位符)。
答案 1 :(得分:1)
Twisted的内置日志观察器不支持Unicode。有关为此添加支持的进展情况,请参阅http://twistedmatrix.com/trac/ticket/989,或了解您可以采取哪些措施来提供帮助。
在#989解决之前,修复程序在Twisted版本中部署了应用程序,请不要记录unicode。只记录str
。