Python中文編碼弄到懷疑人生 原

    新的一個功能因爲用到部分pandas的功能,所以python還是很好的一個用的語言。但是在處理中文,真是讓人對這個編碼有學習了一遍。

    簡單的總結幾點,回憶一下排查過程。大家在碰到這個問題的時候也能夠提供簡單參考。

    1,python語言本身開頭添加# -*- coding: utf-8 -*-。這個是幹啥用的,按照PEP 0263的描述: -- Defining Python Source Code Encodings,避免python代碼裏面有中文而報錯

    2,如果python是2的版本,需要在python腳本import後添加sys.setdefaultencoding('utf8')的語言描述,因爲2的默認編碼是ascii,避免隱式轉換。

    3,對於有數據庫讀取數據的,比如mysql數據庫編碼是utf8,要在連接參數加上“charset=utf8”,顯示指明編碼。

    4,讀出的中文編碼在終端打印的時候可能是亂碼,需要看終端顯示的編碼。

    5,筆者用的是python3,還是少了很多麻煩,不用去設置sys.setdefaultcharset,也不必擔心當前變量是不是Unicode。因爲python3默認就是字符串,也可以理解爲就是Unicode。這個時候想要對其編碼只能用encode,然後返回的是bytes類型。下面是測試例子、

python2.7的情況

>>> s = "你好"
>>> s
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> su = u"你好"
>>> su
u'\u4f60\u597d'
>>> print su
你好
>>> print s
你好
>>> s.decode('utf8')
u'\u4f60\u597d'
>>> print s.decode('utf8')
你好

python3.6的情況

>>> s = '你好'
>>> s
'你好'
>>> type(s)
<class 'str'>
>>> s.encode('utf8')
b'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> s.encode('gbk')
b'\xc4\xe3\xba\xc3'
>>> s.decode('utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'decode'
>>> 
>>> print(s)
你好
>>> su8 = s.encode('utf8')
>>> su8
b'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> print(su8)
b'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> print(su8.decode('utf8'))
你好

大家可以仔細對比下。python2稍微混些,因爲字符串也是能夠decode。

其實python語言對字符串的設計也是讓人容易迷惑。python裏面理解Unicode是文本字符串,而str是字節字符串。python語言不過是默認屏蔽掉這點讓我們無感的使用。但是對於java或者其他語言是不把字節當字符串來處理的。

所以這點的建議是不要對Unicode使用str方法,也不要對str變量使用Unicode,謹記。特別是在2.7的版本。在處理字符串的時候使用正確解碼,當應用從外部讀取數據時,應將其視爲字節串str類型,接着調用.decode() 將其解釋成文本。同樣在將文本發送到外部時,總是對文本調用.encode()。 

 

6,在讀入或者寫入的時候,也要指明編碼。

筆者在向文本寫數據的時候代碼如下:

username = row[0]
fd = open('/tmp/t.csv', 'w')
fd.write(username)
fd.close()

在pandas讀取的時候,報錯UnicodeDecodeError: 'utf-8' codec can't decode byte 0xca in position 0: invalid continuation byte。報這個錯誤是因爲提供給pandas的文本不是utf8編碼。把文本下載到windows系統看了看,其文本編碼爲ANSI。文本中文也能正確展示,但是提示需要選擇編碼。之前有見過這個編碼但是不瞭解是什麼東西,筆者查了下其實就是一種本地化的ASCII編碼的擴展集。就是會根據系統來選擇對於的編碼來展示。這個時候想起寫文本的時候,是不是有第三個參數。一查果然有加上'utf-8'就可以正常執行了。

    最後建議還是早點升級python3的版本,幸福一點。理解編碼原理,Unicode是一種編碼規範,而UTF-8是一種實現方案。encode和decode的對於中間碼Unicode來講的。

 

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