如果在控制台中运行这个代码 – 它的工作原理很好(它是俄语的),但是如果像Apache2服务器上的cgi一样运行,它将失败:< type'exceptions.UnicodeEncodeError'> ;:'ascii'编解码器不能对字符进行编码在位置8-9:序数不在范围(128).代码是:
#!/usr/bin/env python # -*- coding: UTF-8 -*- import cgitb cgitb.enable() print "Content-Type: text/html;charset=utf-8" print s=u'Nikolja \u043d\u0435 \u0421\u0430\u0440\u043a\u043e\u0437\u0438!' print s#.encode('utf-8')
是的,解决方案是取消注释.encode(‘utf-8’),但是我花更多的时间来了解为什么会发生,我无法看到答案.
解决方法
当从控制台运行时,Python可以检测控制台的编码,并将打印到控制台的Unicode隐式转换为该编码.如果编码不支持您要打印的字符,它仍然可能会失败. UTF-8可以支持所有的Unicode字符,但其他常见的控制台编码,如美国Windows上的cp437不支持.
当stdout不是控制台时,如果无法确定控制台编码,则Python 2.X将默认为ASCII.这就是为什么在一个网络服务器中,你必须明确地编码你自己的输出.
例如,从控制台和Web服务器尝试以下脚本:
import sys print sys.stdout.encoding
从控制台你应该得到一些编码,但从Web服务器你应该得到无.请注意,Python 2.X使用ascii,但Python 3.X在无法确定编码时使用utf-8.
import sys print >>sys.stderr,sys.stdout.encoding print >>sys.stderr,sys.stderr.encoding
直接运行时重新导向stdout时返回以下内容:
C:\>test cp437 cp437 C:\>test >out.txt None cp437
注意stderr没有受到影响,因为它没有重定向.
环境变量PYTHONIOENCODING也可用于覆盖默认的stdout / stdin编码.