python编码问题之——Decode error - output not utf-8

Decode error - output not utf-8这个问题,如果用sublime text2下运行python2。就知道这个坑有多大。python3的默认是Unicode,python2的是ascii。所以搜了好多资料,总结一下。


分析各个配置的作用。

1、# -*- coding: utf-8 -*-
用于说明源文件使用的编码,如果没有这个说明,源文件中有中文字符的时候会报SyntaxError: Non-ASCII character这样的错误。


2、sys.setdefaultencoding('utf-8')
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
这样是用于设置默认的编码格式——utf-8,由于模块加载的过程中setdefaultencoding会被删除,所以重新加载sys
后重新设置


3、"default_encoding": "UTF-8",
在sublime的preferences的Setting-Default中,"default_encoding": "UTF-8"是配置sublime环境下的编码


4、Python.sublime-build中的设置
{
"cmd": ["python", "-u", "$file"],
"path":"C:/Python27",
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python",
"shell":"true",
"encoding": "utf-8"
}
这个设置跟sublime下运行python的编码有关,反正"encoding": "utf-8"保证整套编码都是utf-8
相信很多人已经和我这样设置和配置好了,一般的解码编码中文没什么问题。
但是坑该来的还是来了。
我在及在爬取知乎的时候,发现知乎请求返回的json串中的中文用了Unicode转换。还是出现了
Decode error - output not utf-8问题。


Decode error - output not utf-8问题

import requests
import ConfigParser
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

print sys.getdefaultencoding()
print sys.stdin.encoding
print sys.stdout.encoding

f='\u56fd\u5185\u6709\u54ea\u4e9b\u51b7\u95e8\u4f46\u6709\u7279\u8272\u7684\u65c5\u6e38\u5730\u70b9\uff1f'  
print(f.decode('unicode-escape'))

当我这样输出的时候,发现解码是有问题的。现在是把Unicode转换成中文,可以使用decode('unicode-escape')。
但是出现了Decode error - output not utf-8
最让人蛋疼的是,有时是正常可以输出中文——国内有哪些冷门但有特色的旅游地点?有时报Decode error - output not utf-8错误。


然后后面直接在dos窗口和Eclipse的pydev环境下运行,都是正常的。


Decode error - output not utf-8问题原因

原因在哪里呢?
注意,我写多了两句。

print sys.stdin.encoding
print sys.stdout.encoding

在sublime text2输出的是None None
在Eclipse 输出的是     UTF-8 UTF-8
在dos 输出的是         CP936 CP936
这两句指的是输入和输出的编码。所以sublime下clt+b的运行时的这两者编码是未知的。


解决办法

暂时没有好的方法。
蹊跷的是,我发现了这样写可以不会再报这个错误。

import requests
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

print sys.getdefaultencoding()
print sys.stdin.encoding
print sys.stdout.encoding

f='\u56fd\u5185\u6709\u54ea\u4e9b\u51b7\u95e8\u4f46\u6709\u7279\u8272\u7684\u65c5\u6e38\u5730\u70b9\uff1f'  
print type(f.decode('unicode-escape'))
f='\u56fd\u5185\u6709\u54ea\u4e9b\u51b7\u95e8\u4f46\u6709\u7279\u8272\u7684\u65c5\u6e38\u5730\u70b9\uff1f'  
print(f.decode('unicode-escape'))

输出type是'unicode',后面的解码不再报错。至于为什么这样我也想不明白,但是sublime调了一些快捷键之后,用得比较爽。
如果不想这样的话可以换个IDE。

你可能感兴趣的:(python,unicode,编码,utf-8,ASCII)