因為中文的特殊編碼,導致 Python2 和 Python3 使用過程中的各種編碼問題,如果不清楚其中的關聯關系,那么這就一直是個大坑,不是懵逼就還是懵逼,所以就目前碰到的情況徹底梳理下 Python2 和 Python3 中編碼的關系和區別,以作備忘。
先說下涉及編碼格式的幾個地方:
# -*- coding: utf-8 -*-
,如果使用 Python2,沒有顯式聲明的話默認使用 ASCII 格式,Python3 默認使用 utf-8 格式;sys.getdefaultencoding()
查看,Python2 默認是 ASCII,Python3 默認使用 utf-8;下面我們把上述編碼分別在腳本中進行組合使用后,再使用 Python2.6 和 Python3.4 運行,看看實際都什么效果。
腳本內容:
import sys
print(sys.getdefaultencoding())
print('中文')
使用 Python2.6 運行的結果如下,提示gbk 編碼字符 \xd6
非 ASCII 字符:
> python26 test_gbk.py
File "test_gbk.py", line 4
SyntaxError: Non-ASCII character '\xd6' in file test_gbk.py on line 4, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
使用 Python3.4 運行的結果如下,提示gbk 編碼字符 \xd6
非 utf-8 字符:
> python26 test_gbk.py
File "test_gbk.py", line 4
SyntaxError: Non-UTF-8 code starting with '\xd6' in file test_gbk.py on line 4, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
結論:默認的 gbk 編碼中文,Python2的解釋器字符編碼(ASCII)和 Python3的解釋器字符編碼(utf-8)格式都沒法識別,因為 ASCII 編碼不包含中文,而 utf-8 是 3 字節編碼,gbk 是 2 字節編碼,所以都識別不了了。
在剛才的腳本頭部顯式聲明腳本文件編碼格式為 gbk:
#coding:gbk
import sys
print(sys.getdefaultencoding())
print('中文')
使用 Python2.6 運行的結果:
> python26 test_gbk.py
ascii
中文
使用 Python3.4 運行的結果:
> python34 test_gbk.py
utf-8
中文
結論:文件使用的 gbk 格式存儲,同時顯式聲明了腳本文件編碼為 gbk,Python2 和 Python3 都可以正常處理。
在剛才的腳本頭部顯式聲明腳本文件編碼格式為 utf-8:
# -*- coding: utf-8 -*-
import sys
print(sys.getdefaultencoding())
print('中文')
使用 Python2.6 運行的結果正常:
> python26 test_gbk.py
ascii
中文
使用 Python3.4 運行的結果如下,提示嘗試使用 utf-8 解碼字符 0xd6
時異常:
> python34 test_gbk.py
File "test_gbk.py", line 6
SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xd6 in position 0: invalid continuation byte
結論:文件使用的 gbk 格式存儲,同時顯式聲明了腳本文件編碼為 utf-8時,但是 Python2 在 Windows 平臺還是使用 gbk 進行輸出,所以解析正常,而 Python3 使用 utf-8 所以解析異常。
去掉之前腳本頭部的聲明,然后使用 utf-8 格式存儲文件(注意,不能在剛才的文件基礎上強制修改存儲編碼,強制轉換會出現中文亂碼的問題,建議先新建一個 utf-8 格式的文件,然后再輸入中文):
import sys
print(sys.getdefaultencoding())
print('中文')
使用 Python2.6 運行的結果如下,ASCII 也識別不了 utf-8 格式的字符 \xe4
:
> python26 test.py
File "test.py", line 4
SyntaxError: Non-ASCII character '\xe4' in file test.py on line 4, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
使用 Python3.4 運行的結果,可以正常識別,因為 Python3 默認使用 utf-8 編碼:
> python34 test.py
utf-8
中文
結論:默認的 utf-8 編碼中文,Python2 會默認使用 ASCII 讀取,所以沒法識別,Python3 可以正常識別。
腳本頭部顯式聲明腳本文件編碼格式為 gbk,同時使用 utf-8 格式存儲文件:
#coding:gbk
import sys
print(sys.getdefaultencoding())
print('中文')
使用 Python2.6 運行的結果如下,使用 gbk 根本讀取不了 utf-8 格式任何內容:
> python26 test.py
File "test.py", line 6
SyntaxError: 'gbk' codec can't decode bytes in position 9-10: illegal multibyte sequence
使用 Python3.4 運行的結果如下,其實和上面錯誤一樣,但是提示更直接了:
> python34 test.py
File "test.py", line 1
SyntaxError: encoding problem: gbk
結論:默認的 utf-8 編碼中文,如果顯式指定使用 gbk 讀取,Python2 和 Python3 都沒法做到。
腳本頭部顯式聲明腳本文件編碼格式為 utf-8,同時使用 utf-8 格式存儲文件:
# -*- coding: utf-8 -*-
import sys
print(sys.getdefaultencoding())
print('中文')
使用 Python2.6 運行的結果如下,雖然讀取正確了,但是 Python2 在 Windows 系統會默認使用 gbk 對中文進行解碼,所以輸出亂碼:
> python26 test.py
ascii
涓枃
使用 Python3.4 運行的結果正常:
> python34 test.py
utf-8
中文
結論:雖然文件存儲編碼和腳本文件編碼都是 utf-8,但是 Windows 平臺上,Python2 會按 gbk 解析中文,所以會輸出亂碼,可以在中文前面加 u 來解決u'中文'
,或者顯式使用 utf-8 進行一次 decode。
匯總下驗證結果,可以得到如下的表格:
不同組合下 Python3 和 Python2 處理結果 | Python3 | Python2 |
---|---|---|
默認腳本文件編碼 + 文件存儲使用 gbk | SyntaxError,解析錯誤 | SyntaxError,解析錯誤 |
腳本文件編碼 gbk + 文件存儲使用 gbk | 正常輸出中文 | 正常輸出中文 |
腳本文件編碼 utf-8 + 文件存儲使用 gbk | SyntaxError,解析錯誤 | 正常輸出中文 |
默認腳本文件編碼 + 文件存儲 utf-8 | 正常輸出中文 | SyntaxError,解析錯誤 |
腳本文件編碼 gbk + 文件存儲使用 utf-8 | SyntaxError,解析錯誤 | SyntaxError,編碼錯誤 |
腳本文件編碼 utf-8 + 文件存儲使用 utf-8 | 正常輸出中文 | 中文輸出亂碼 |
本文原創發布于公眾號「sylan215」,十年測試老兵的原創干貨,關注我,漲姿勢!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。