標籤:沒有 對應關係 file 之間 python3 種類 地方 範圍 character
python運行時出現UnicodeDecodeError,UnicodeEncodeError錯誤時,應該如何去面對,解決。電腦處理文本時必須先轉換為數字。電腦採用二進位。
字串編碼
(1)通用的unicode
(2)將unicode編碼轉換為某種類型的編碼
位元組
資料存放區基本單元,一位元組等於8bit,所以一個位元組對應256種狀態。
字元
字元一個資訊單位,它是各種文字和符號的統稱,比如一個英文字母是一個字元,一個漢字是一個字元,一個標點符號也是一個字元
字元集
個範圍內字元的集合,不同的字元集規定了字元的個數。ASCII 字元集總共有128個字元,包含了英文字母、阿拉伯數字、標點符號和控制符。GB2312 字元集定義了7445個字元,包含了絕大部分漢字字元
字元碼
將字元集中的字元碼映射為位元組流的一種具體實現方案,常見的字元編碼有 ASCII 編碼、UTF-8 編碼、GBK 編碼
字元集與字元編碼有種對應關係,
例如 ASCII 字元集對應 有 ASCII 編碼。ASCII 字元編碼規定使用單位元組中低位的7個位元去編碼所有的字元。例如"A" 的編號是65,用單位元組表示就是0×41,因此寫入存放裝置的時候就是b‘01000001‘。
編碼、解碼
編碼的過程是將字元轉換成位元組流,解碼的過程是將位元組流解析為字元。
ASCII 編碼
為對應英文字元和二進位的關係,128字元編碼
GB2312
中文常見編碼方式,兩位元組表示一個漢字 理論有256x256=65536個符號
Unicode 統一碼,萬國碼,單一碼
能夠跨語言 跨平台進行文本轉換與處理
unicode編碼兩個位元組,Ascii一個位元組
A的ASCII編碼:01000001 ,Unicode編碼:0000000001000001 儲存起來浪費空間,比ascii浪費一倍多,為節省空間的 之間格式字元集,utf-8和utf-16
UTF
變長的字元編碼,1-4個位元組來表示一個字元,英文字母被編譯為一個位元組,漢字3個位元組。
UTF-8的編碼規則:
a.對於單位元組符號,位元組第一位設定為0,後面7位為這個位元組的unicode編碼,英文字母utf-8和ascii碼是相同的b.對於n位元組符號(n>1) 第一個位元組的前n位都設定為1,第n+1位設定為0,後面位元組的前兩位一律設定為10剩下的沒有提及的二進位位全部為這個符號的unicode編碼
編碼對照案例:
在py3中 字串編碼使用str和bytes
(1)str字串:使用Unicode編碼
(2)bytes字串:將unicode編碼轉換為某種類型的編碼如utf-8
python3中預設編碼unicodeencode和decode
encode 負責將unicode 編碼成指定的字元編碼
decode將其他字元編碼轉換為unicode編碼
UnicodeEncodeError 和 UnicodeDecodeError 錯誤的原因
UnicodeEncodeError 和 UnicodeDecodeError 錯誤了,這些錯誤的根本原因在於 Python2 預設是使用 ascii 編碼進行 decode 和 encode 操作
>> s = ‘我們‘
>> s.decode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xe4 in position 0: ordinal not in range(128)
當把 s 轉換成 unicode 類型的字串時,decode 方法預設使用 ascii 編碼進行解碼,而 ascii 字元集中根本就沒有中文字元『你好』,所以就出現了 UnicodeDecodeError,正確的方式是顯示地指定 UTF-8 字元編碼。
>> s.decode(‘utf-8‘)
u‘\u4f60\u597d‘
對於 encode 操作,把 unicode字串轉換成 str類型的字串時,預設也是使用 ascii 編碼進行編碼轉換的,而 ascii 字元集找不到中文字元『你好』,於是就出現了UnicodeEncodeError 錯誤。
>> a = u‘我們‘
>> a.encode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in position 0-1: ordinal not in range(128)
str 類型與 unicode 類型的字串混合使用時,str 類型的字串會隱式地將 str 轉換成 unicode字串,如果 str字串是中文字元,那麼就會出現UnicodeDecodeError 錯誤,因為 python2 預設會使用 ascii 編碼來進行 decode 操作。
>> s = ‘你好‘ # str類型
>> y = u‘python‘ # unicode類型
>> s + y # 隱式轉換,即 s.decode(‘ascii‘) + u
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xe4 in position 0: ordinal not in range(128)
正確地方式是顯示地指定 UTF-8 字元編碼進行解碼
>> s.decode(‘utf-8‘) +y
u‘\u4f60\u597dpython‘
所有出現亂碼的原因都可以歸結為字元經過不同編碼解碼在編碼的過程中使用的編碼格式不一致
python字元編碼