python 的編碼問題,應該每一個寫python代碼的童鞋都被困擾過。
別外python2 和 python3 的預設編碼又不同,所以弄清楚還是有必要的,不然在網上搜一堆答案一個一個試,還是挺浪費時間的。
首先,python 2.x 的 str
s = "我不是亂碼"
s是個字串,它本身儲存的就是位元組碼(bytes)。
那麼這個位元組碼是什麼格式的。
如果這段代碼是在解譯器上輸入的,那麼這個s的格式就是解譯器的編碼格式,對於windows的cmd而言,就是gbk。
如果將段代碼是儲存後才執行的,比如儲存為utf-8,那麼在解譯器載入這段程式的時候,就會將s初始化為utf-8編碼。
python 2.x 的 unicode
我們知道unicode是一種編碼通訊協定,具體的實現標準可能是utf-8,utf-16,gbk ……
python 在內部使用兩個位元組來儲存一個unicode,使用unicode對象而不是str的好處,就是unicode方便於跨平台。
你可以用如下兩種方式定義一個unicode:
s1 = u"我不是亂碼" s2 = unicode("我不是亂碼", "utf-8")
可以通過 encode與decode 進行轉換。
但Python 2 悄悄掩蓋了 byte 到 unicode 的轉換,讓程式在處理 ASCII 的時候更加簡單。你付出的代價就是在處理非 ASCII 的時候將會失敗。
我們經常碰到錯誤是 UnicodeDecodeError: ‘ascii’ codec can’t decode byte ……
常用解決方案:
設定defaultencoding
reload(sys)sys.setdefaultencoding('utf-8')
如果你在python中進行編碼和解碼的時候,不指定編碼方式,那麼python就會使用defaultencoding。
比如上一節例子中將str編碼為另一種格式,就會使用defaultencoding。
s.encode("utf-8") 等價於 s.decode(defaultencoding).encode("utf-8")
再比如你使用str建立unicode對象時,如果不說明這個str的編碼格式,那麼程式也會使用defaultencoding。
u = unicode("人生苦短") 等價於 u = unicode("人生苦短",defaultencoding)
預設的defaultcoding:ascii是許多錯誤的原因,所以早早的設定defaultencoding是一個好習慣。
檔案頭聲明編碼的作用
頂部的:# -- coding: utf-8 --目前看來有三個作用。 如果代碼中有中文注釋,就需要此聲明 比較進階的編輯器(比如我的emacs),會根據頭部聲明,將此作為代碼檔案的格式。 程式會通過頭部聲明,解碼初始化 u’人生苦短’,這樣的unicode對象,(所以頭部聲明和代碼的儲存格式要一致)
在python3 中
Python 3 也有兩種類型,一個是 str(unicode),一個是 byte 碼。但是它們有不同的命名。 type(變數)
Python 3 中對 Unicode 支援的最大變化就是沒有對 byte 字串的自動解碼。如果你想要用一個 byte 字串和一個 unicode 相串連的話,你會得到一個錯誤,不管包含的內容是什麼。
可以簡單理解為:
python2 中的unicode -> python3 的str
python2 中的str-> python3 的byte
個人認為下面這篇文章圖文並茂的說明了各種字元的關係,值得仔細閱讀一下。
http://pycoders-weekly-chinese.readthedocs.io/en/latest/issue5/unipain.html
參考:
http://python.jobbole.com/81244/