填一填python2.x 中文字元編碼的坑

Gladyu發表於2019-03-02

背景

python作為最優雅的語言之一一直倍受大家的青睞。它可以幫你從單調重複的工作解脫出來,比如統計各種蛋疼的資料,匯入匯出boss需要的表格等等。你要做的是編寫、執行python指令碼,然後喝個茶水等著執行結果就好了。

這篇文章就是這樣產生的—-在我使用scrapy爬取資料的時候,遇到了python 2.x 中文字元編碼的問題,以前對這個問題也是一知半解,這次再次遇到說明要還債了,去搞清楚字元編碼到底是怎麼一回事。

預備知識

ASCII

首先,我們需要明確在計算機中所有資訊最終都是使用二進位制表示的,每個二進位制位(bit)有0和1兩種狀態,8個二進位制位被稱為一個位元組(byte),可以表示256種狀態。

作為計算機領域的先驅,美國在上世紀60年代制定了一套字元編碼,使用二進位制來表示英文字母、數字及一些符號,這套字元編碼就是ASCII

Unicode

隨著計算機的發展,很快有了其他語言的編碼需求,單位元組的ASCII編碼由於能表示的字元有限,已經不能滿足需求了。為了不與ASCII編碼衝突,有能力的國家開始設計單獨的編碼—-使用更多的位元組表示字元,中國製定了gb2312

但是,隨之而來的是字元編碼方案數量增加帶來的一系列問題。因此,Unicode應運而生。它把所有語言的字元都用同一種字符集來表示,解決了因不同字元編碼方案帶來的一系列問題

然後來說說Python 2.x 中文編碼問題

先給大家來一個簡單的?,比較常見

檔案test.py內容:

#!/usr/bin/python
city = `京`
print city
複製程式碼

執行python test.py,結果如圖:

填一填python2.x 中文字元編碼的坑

那為什麼那?
如果你不知道,說明你沒有仔細看預備知識。這是因為.py檔案預設採用的是ASCII編碼,中文字元不在它表示的範圍內,報錯

通過修改test.py預設編碼方式解決

#!/usr/bin/python
# -*- coding: utf-8 -*-
city = `京`
print city
複製程式碼

看過了?,再來看看str和unicode

填一填python2.x 中文字元編碼的坑
填一填python2.x 中文字元編碼的坑

str和unicode都是basestring的子類。但是,嚴格來說unicode是真正意義上的字串,str是位元組碼—-由unicode經過編碼後的位元組組成的序列
上個截圖,消除大家的疑惑,s == s2

填一填python2.x 中文字元編碼的坑

通過這個?,理解str和unicode的區別,媽媽再也不擔心處理中文字元時出現亂碼或報錯了(不論是unicode轉str,還是str轉unicode),還要避免如下操作

  • 1.對中文的unicode進行decode,非法
  • 2.對中文的str進行encode,非法

說了這麼多,show me you code (斜眼笑)?:

#!/usr/bin/python
# -*- coding: utf-8 -*-
u_z = u`京`
s_z = `京`
u=u`jing`
s=`jing`

print u_z
print s_z
print repr(u_z)
print repr(s_z)

print `==================`

print u
print s
print repr(u)
print repr(s)

print `==================`

print u.decode()
print s.encode()

print u_z.decode()
print s_z.encode()
複製程式碼

一點建議

  • 同一工程下,統一原始檔字元編碼、統一系統字元編碼,防止亂碼
    #!/usr/bin/python
    # -*- coding:utf8 -*-
    import sys
    reload(sys)
    sys.setdefaultencoding("utf-8")
    複製程式碼
  • 儘量使用unicode
  • 陣列,字典存入資料庫前,進行json.dumps
  • decode和encode格式統一

好了,這就是我對python2.x 中文字元編碼的一些理解,希望可以幫到你

未經本人允許,不得轉載。文章有疏漏淺薄之處,請各位大神斧正

相關文章