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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章