天天看點

【Python】編碼和字元串

編碼和字元串

編碼

在學習回顧中總結一下ASCII編碼、Unicode編碼和utf-8編碼。

計算機中隻能處理數字,我們若要處理文本的話就要将檔案轉換為數字。是以,這就涉及該怎樣轉換的問題,也就是編碼問題。

在計算機中使用8個比特(bit)作為一個位元組(byte),一個位元組最大的表示範圍是255(從0開始),意味着一個位元組最多表示256個字元,表示更多的字元需要更多的位元組。

ASCII編碼

因為計算機是美國人發明的,是以最早就隻有127個字元被編碼到計算機中。127個字元包括大小寫英文字母、數字和一些符号。這個編碼也被稱為ASCII編碼。在ASCII碼表中記錄着127個字元所對應的十六進制和十進制等資訊。

附一張ASCII碼表的截圖。

【Python】編碼和字元串

Unicode編碼

見名知意,Unicode編碼的意思就應該是統一編碼之意。早期計算機剛誕生之時隻做軍隊和大學研究之用不算普遍,可是後面發展迅速,在很多國家都在廣泛使用計算機。為了能讓各個國家統一處理語言編碼問題就需要一種統一的編碼,最開始的ASCII編碼僅能表示256個字元遠遠不能滿足需求,是以就産生了Unicode編碼。

Unicode編碼最常用的是兩個位元組表示一個字元(如果是非常偏僻的字元則需要四個位元組)

utf-8

實際上,Unicode的實作方式不同于編碼方式。一個字元的Unicode編碼是确定的。但是在實際傳輸過程中,由于不同系統平台的設計不一緻,以及出于節省空間的目的,對Unicode編碼的實作方式會有所不同。Unicode的實作方式稱為Unicode轉換格式(Unicode Transformation Format,簡稱為UTF)

如果一個僅包含基本7位ASCII字元的Unicode檔案,如果每個字元都使用2位元組的原Unicode編碼傳輸,其第一位元組的8位始終為0。這就造成了比較大的浪費。對于這種情況,可以使用UTF-8編碼,這是一種

變長編碼

,UTF-8編碼把一個Unicode字元根據不同的數字大小編碼成1-6個位元組,常用的英文字母被編碼成1個位元組,漢字通常是3個位元組,隻有很生僻的字元才會被編碼成4-6個位元組。

是以,如果你要傳輸的文本包含大量英文字元,用UTF-8編碼就能節省空間。

字元串

在Python3中,文本是Unicode編碼,由str類型表示,二進制資料則由bytes類型表示。

需要注意Python對bytes類型資料用帶b字首的單引号或雙引号表示如:x=b'time'

當資料儲存在磁盤上或者在網絡上傳輸時,我們需要将str類型資料轉換為二進制資料類型bytes。

以Unicode表示的str可以通過encode()方法編碼為指定的bytes

>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
           

以上可以也證明中文編碼不能用ascii編碼

如果我們從網絡或磁盤上讀取了位元組流,那麼讀到的資料就是bytes。要把bytes變為str,就需要用decode()方法。

當然,bytes中可能包含無法解碼的位元組,這時decode()方法會報錯,如果bytes中隻有一小部分無效的位元組,可以傳入errors='ignore'忽略錯誤的位元組

>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
>>> b'\xe4\xb8\xad\xff'.decode('utf-8')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte
>>> b'\xe4\xb8\xad\xff'.decode('utf-8',errors='ignore')
'中'
           

還有一點需要注意一下,len()函數計算的是str的字元數,如果換成bytes,len()函數就計算位元組數

>>> len('中文'.encode('utf-8'))
6
>>> len('中文')
2
           

每天進步一點點,不要停止前進的腳步~

繼續閱讀