1. 程式人生 > >Python 中的編碼與解碼

Python 中的編碼與解碼

Python2.x 和 Python3.x 中關於字元編碼的問題



1. 一些基本的概念

  • 位元 / bit:計算機中最小的資料單位,是單個的二進位制數值 0 或1
  • 位元組 / byte:計算機儲存資料的單元,1 個位元組由 8 個位元組成
  • 字元:人類能夠識別的符號
  • 編碼:將人類可識別的字元轉換為機器可識別的位元組碼 / 位元組序列
  • 解碼:編碼的反向過程叫解碼
  • 概述:Unicode 是人類可識別的字元格式;ASCII 、UTF-8 、GBK 等都是機器可識別的位元組碼格式。我們寫在檔案中的 py3 程式碼,是由字元組成的,它們的格式,就是 Unicode,而字元是以位元組為儲存單位儲存在檔案中,檔案儲存在記憶體 / 物理磁碟中

2. 編碼格式

Python2 的預設編碼是 ASCII,不能識別中文字元,需要顯式指定字元編碼。

Python3 的預設編碼為 Unicode,可以識別中文字元。

計算機記憶體中的資料,統一使用 Unicode 編碼。

資料傳輸或儲存到硬碟上,使用 UTF-8 編碼。

3. 編碼和解碼

​編碼 / encode:將 Unicode 字串轉換為特定編碼格式對應的位元組碼的過程。
解碼 / decode:將特定編碼格式的位元組碼轉換為對應的 Unicode 字串的過程。

In [1]: '美麗人生'.encode('gbk')
Out[1]: b'\xc3\xc0\xc0\xf6\xc8\xcb\xc9\xfa'

In [2]: b'\xc3\xc0\xc0\xf6\xc8\xcb\xc9\xfa'.decode('gbk')
Out[2]: '美麗人生'

In [3]: '美麗人生'.encode('utf-8')
Out[3]: b'\xe7\xbe
\x8e\xe4\xb8\xbd\xe4\xba\xba\xe7\x94\x9f' In [4]: b'\xe7\xbe\x8e\xe4\xb8\xbd\xe4\xba\xba\xe7\x94\x9f'.decode('utf-8') Out[4]: '美麗人生' In [5]: b'\xe7\xbe\x8e\xe4\xb8\xbd\xe4\xba\xba\xe7\x94\x9f'.decode('gbk').encode('u ...: tf-8') Out[5]: b'\xe7\xbc\x87\xe5\xba\x9d\xe9\x99\x84\xe6\xb5\x9c\xe8\x99\xb9\xe6\x95\x93'

​上面這種以 b 開頭的就是位元組碼,一個斜槓就是一個位元組。可見,一個常用漢字用 GBK 格式編碼後佔 2 個位元組,用 UTF-8 格式編碼後佔 3 個位元組。因為儲存或傳輸時,也用 UTF-8 編碼,所以一個漢字佔的空間就是 3 個位元組。

字串長度和位元組碼長度:

In [6]: len('美麗人生')
Out[6]: 4

In [7]: len(b'\xe7\xbc\x87\xe5\xba\x9d\xe9\x99\x84\xe6\xb5\x9c\xe8\x99\xb9\xe6\x95\x93')
Out[7]: 18

4. Python3 的預設編碼

​例如我們用編輯器開啟一個檔案,輸入 a,這個 a 就是 Uincode 字元。當我們儲存檔案,這個字元就會根據編輯器的設定被轉換為對應的編碼格式的位元組碼儲存到系統硬碟。這是一個 encode 過程
Python 直譯器執行檔案時,先將檔案位元組碼按照指定的編碼格式解碼為字元,然後執行程式。這是一個 decode 過程
指定編碼,在檔案開頭,例如:Python 檔案通常這樣寫:# -*- coding:utf-8 -*-;HTML 檔案通常這樣寫:<meta charset='utf-8'>,意思就是該檔案是 UTF-8 編碼格式,按這個格式解碼
上文提到 Python3 的預設編碼是 UTF-8。即如果檔案未標明編碼格式,直譯器會自動按照 UTF-8來解碼。當直譯器無法通過指定的或預設的編碼格式對檔案進行轉換 / 解碼時,就會出現解碼錯誤:UnicodeEncodeError