一個很難找到問題所在的問題,後來是經過網上的博文才知道了是怎麼樣的緣由,reload(sys)不能隨便用,由於一旦重置了,不少環境變量就不同了。python
首先是問題的來源:ubuntu
我在寫python腳本遇到了下面這個問題函數
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
至關不能理解,這其實就涉及了python裏面至關複雜的編碼的問題。在python中運行的字符串都是unicode編碼的,爲何須要這麼一箇中間的編碼,實際上是頗有用的,保證了編碼與編碼之間的互通性。編碼
首先,你們確定知道encode和decode,用法以下code
str = 'dafd' unicode_str = str.decode('gb2312') #這表示將gb2312編碼的str轉化成unicode unicode_str.encode('utf-8') #這表示將unicode編碼的unicode_str轉化成utf-8編碼
所以,轉碼的時候必定要先搞明白,字符串str是什麼編碼,而後decode成unicode,而後再encode成其餘編碼utf-8
另外,
代碼中字符串的默認編碼與代碼文件自己的編碼一致。記住!~ci
如:s='中文' 若是是在utf8的文件中,該字符串就是utf8編碼,若是是在gb2312的文件中, 則其編碼爲gb2312。這種狀況下,要進行編碼轉換, 都須要先用decode方法將其轉換成unicode編碼, 再使用encode方法將其轉換成其餘編碼。一般,在沒有指定特定的編碼方式時,都是使用的系統默認編碼建立的代碼文件。 若是字符串是這樣定義:s=u'中文' 則該字符串的編碼就被指定爲unicode了,即python的內部編碼, 而與代碼文件自己的編碼無關。所以,對於這種狀況作編碼轉換,只須要直接使用encode方法將其轉換成指定編碼便可。
若是一個str已是unicode了,這時候再去decode就會出錯,很好理解。unicode
得到系統的默認編碼字符串
#!/usr/bin/env python #coding=utf-8 import sys print sys.getdefaultencoding() 該段程序在英文WindowsXP上輸出爲:ascii 但其實在ubuntu裏也是這樣的問題,這其實就是我寫這篇文章的初衷,由於我被這個問題困擾了好久! s = '你好' print s
輸出控制檯的編碼是ascii時,若是你print的是unicode就會出現這個錯誤:terminal
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
只要改爲 print s.encode('utf-8')就ok了。
剛剛這麼講好像就解決了?其實不是的,我有個函數tf.train.BytesList,這個函數的參數是一個str,可是這個str的編碼由於系統默認編碼的緣由出錯了,就是上面的錯。這時候的解決辦法通常是reload(sys)。
可是,你會看到卡住了?實際上是輸出看不到了,網上有這樣的解答。
IDLE做爲一個GUI Shell環境,在啓動初始化過程當中, 會設置特定的標準輸入、標準輸出和標準錯誤輸出,使得輸入和輸出都在IDLE的GUI Shell中。 而若是手動執行了reload(sys)之後,sys模塊的這三個變量將會被重置, 致使輸出沒法顯示在IDLE。因此解決方案很簡單,只須要在reload以前把這三個變量都複製一份,reload以後再恢復回來就好了
上面的IDLE其實不僅是IDLE,像我就是在jupyter的狀況下出錯的,terminal下也是同樣。因此要記得補上如下代碼:
stdi,stdo,stde=sys.stdin,sys.stdout,sys.stderr reload(sys) sys.stdin,sys.stdout,sys.stderr=stdi,stdo,stde
ok!就寫到這,祝你們coding愉快~