Python2編碼問題

2021-07-26 19:51:22 字數 3329 閱讀 5016

以下內容說的都是 python 2.x 版本

我們看到的輸入輸出都是『字元』(characters),計算機(程式)並不能直接處理,需要轉化成位元組資料(bytes),因為程式只能處理 bytes 資料。

例如:檔案、網路傳輸等,處理的都是 bytes 資料——二進位制數字。

孤立的 byte 是毫無意義的,所以我們來賦予他們含義。就引入『字符集』的概念,『字符集』就是乙個碼位(code point)對應的乙個字元的表。

該錶用於賦予 byte 意義。還需要知道乙個點:因為 ascii 字符集支援的字元太少,不能表示各個國家語言中的字元。所以就發明了

unicode ——萬國碼,該字符集包含了你能用到的所有的字元。

在 python 中字串分為兩個物件:strunicode

unicode_obj.encode() ——> bytes 『編碼』(encode)

bytes_obj.decode() ——> unicode 『解碼』(decode)

utf-8 是最流行的一種對 unicode 進行傳播和儲存的編碼方式。所以,多用它作為編碼方式。

s =

'hello'

# str

u =u'你好'

# unicode

back_to_bytes = u.encode('utf-8')

back_to_utf8 = back_to_bytes.decode('utf-8') # 或 unicode(s, 'utf-8')

正如前面所說的,計算機只能操作 bytes,所以 python 在編譯原檔案的時候,會先把原始檔進行編碼,預設以『ascii』進行編碼。這就是為什麼如果原始檔中帶有『中文』,需要在原始檔的起始行宣告編碼方式。

完成編碼後,原始碼中的所有字元,都變成了 bytes 計算機就可以進行編譯和處理了。編譯過程:

讀取檔案

不同的檔案,根據其宣告的編碼去解析為unicode

轉換為utf-8字串

針對utf-8字串,去分詞

編譯,建立unicode物件(python直譯器處理)

根據這個過程,在自己的**中也應該按照這個邏輯處理,意思是:

接收外部資料時,統一轉化為unicode

**內部處理的都是unicode

輸出時統一轉化為utf-8(網路資料傳輸、文字輸出)

參考:pep 263 -- defining python source code encodings

程式中所有的輸入和輸出均為 byte

世界上的文字需要比 256 更多的符號來表現(ascii是不夠的)

你的程式必須能夠處理 byte 和 unicode

byte 流中不會包含編碼資訊(編碼資訊會在:檔案的開頭、協議中等地方宣告)

content-type:text/html; charset=utf-8指明的編碼有可能是錯誤的(出現亂碼)

在 python 中處理編碼問題,會出現很多問題,這裡就不一一枚舉。

這些問題大都是使用了不匹配的編碼方式進行解碼、編碼造成的。而 python 為了語法更加簡介,在一些內建方法中,使用了一些隱性轉換。這種**的轉換帶了的便捷的同時也會帶來一些非預期的錯誤。下面就一一道來。

a = "abc" + u"bcd",python 會如此轉換 "abc".decode(sys.getdefaultencoding()) 然後將兩個 unicode 字元合併。

str:something.encode(sys.getdefaultencoding())

unicode:something.decode(sys.getdefaultencoding())

sys.getdefaultencoding()預設為:ascii,這就是為什麼str(u'中文')unicode('中文')分別會報錯:unicodeencodeerror和unicodedecodeerror。因為ascii編碼方式,編碼/解碼不了中文(支援的字元有限)。

print函式,會對輸出的內容進行編碼,這是因為:所謂的輸出,也是從乙個程式到另外乙個程式。程式之間的互動都是都是傳遞 bytes。比方說print,就是把資料傳遞給終端,終端也是個程式,所以print函式就把需要輸出的內容編碼成了 bytes,採用那種編碼方式,就是

sys.stdout.encoding引數決定的。

在互動環境下(python、ipython)輸入的資料的編碼則由sys.stdin.encoding引數決定。參考:what does python print() function actually do?

python 的預設編髮方式為 ascii。

如何改變python的預設編碼方式?:

import sys

# sys.setdefaultencoding() does not exist, here!

reload(sys) # reload does the trick!

sys.setdefaultencoding('utf8')

為什麼要過載sys模組?

因為如果在編譯.py檔案的之前,改變預設編碼,會影響python的編譯。

當編譯完,再過載sys模組,它就是變成了第三方模組,可以隨便更改,不回影響編譯。setdefaultencoding()函式才可以呼叫。參考:changing default encoding of python?

本片文章沒有列舉出常見的異常,因為如果看懂了上面所有的解釋。再按照下面的姿勢使用,那麼 python2 中的編碼問題,因該就不會再困擾你了。

unicode 三明治:盡可能的讓你程式處理的文字都為 unicode 。如下圖:

了解你的字串。你應該知道你的程式中,哪些是 unicode, 哪些是 byte,對於這些 byte 串。你應該知道,他們的編碼是什麼。(詳情見上述小結第 4 條)

測試 unicode 支援。使用一些奇怪的符號來測試你是否已經做到了以上幾點。(測試看看你的程式是否支援中文)

Python2編碼問題

以下內容說的都是 python 2.x 版本 我們看到的輸入輸出都是 字元 characters 計算機 程式 並不能直接處理,需要轉化成位元組資料 bytes 因為程式只能處理 bytes 資料。例如 檔案 網路傳輸等,處理的都是 bytes 資料 二進位制數字。孤立的 byte 是毫無意義的,所...

python2 編碼問題

coding utf 8 import sys reload sys sys.setdefaultencoding utf8 第一行是讓 以utf8格式解析 後面三行是讓python直譯器在decode時候用utf8進行decode 這樣所有字串都是utf8的了,如果遇到非utf8字串可以用deco...

Python2 的編碼問題

比如這樣乙個字串 u6768 u777f 無論怎麼print它都是這個形式因為它是文字,不是編碼,那麼怎麼轉為中文呢,則需要用如下命令 print text.decode unicode escape 就代表著乙個字 對於這些字元,只需要使用如下命令即可從文字轉為編碼字串 print text.de...