为什么python-cgi在unicode上失败?

如果在控制台中运行这个代码 – 它的工作原理很好(它是俄语的),但是如果像Apache2服务器上的cgi一样运行,它将失败:< type'exceptions.UnicodeEncodeError'&gt ;:'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编码.

相关文章

功能概要:(目前已实现功能)公共展示部分:1.网站首页展示...
大体上把Python中的数据类型分为如下几类: Number(数字) ...
开发之前第一步,就是构造整个的项目结构。这就好比作一幅画...
源码编译方式安装Apache首先下载Apache源码压缩包,地址为ht...
前面说完了此项目的创建及数据模型设计的过程。如果未看过,...
python中常用的写爬虫的库有urllib2、requests,对于大多数比...