關於python編碼,你真的明白了嗎

發表於2016-10-31

計算機儲存的幾個概念

想要徹底搞清楚編碼問題,我們必須要先搞清楚計算機是怎麼儲存資料的,這就涉及到了計算機基礎的幾個概念了,開篇我們就先來捋捋這幾個容易混淆的概念。

bit

二進位制位, 是計算機內部資料儲存的最小單位,11010100是一個8位二進位制數。一個二進位制位只可以表示0和1兩種狀態(2^1);兩個二進位制位可以表示00、01、10、11四種(2^2)狀態;三位二進位制數可表示八種狀態(2^3)……

Byte

位元組,是計算機中資料處理的基本單位,計算機中以位元組為單位儲存和解釋資訊,規定一個位元組由八個二進位制位構成,即1個位元組等於8個位元(1Byte=8bit)。八位二進位制數最小為00000000,最大為11111111;通常1個位元組可以存入一個ASCII碼,2個位元組可以存放一個漢字國標碼。

在計算機中,一串數碼作為一個整體來處理或運算的,稱為一個計算機字,簡稱宇。字通常分為若干個位元組(每個位元組一般是8位)。在儲存器中,通常每個單元儲存一個字,因此每個字都是可以定址的。字的長度用位數來表示。在計算機的運算器、控制器中,通常都是以字為單位進行傳送的。

字長

字長:電腦技術中對CPU在單位時間內(同一時間)能一次處理的二進位制數的位數叫字長。所以能處理字長為8位資料的CPU通常就叫8位的CPU。同理32位的CPU就能在單位時間內處理字長為32位的二進位制資料。

位元組和字長的區別:由於常用的英文字元用8位二進位制就可以表示,所以通常就將8位稱為一個位元組。字長的長度是不固定的,對於不同的CPU、字長的長度也不一樣。8位的CPU一次只能處理一個位元組,而32位的CPU一次就能處理4個位元組,同理字長為64位的CPU一次可以處理8個位元組。

常見的編碼

ASCII: 1個位元組,只編碼英文字母和符號

gb2312: 2個位元組,增加了中文漢字和符號

Unicode: 把所有語言都統一到一套編碼裡把所有語言都統一到一套編碼裡,
一般是2個位元組,生僻字4個位元組

utf-8: 可變長編碼,常用的英文字母被編碼成1個位元組,漢字通常是3個位元組,只有很生僻的字元才會被編碼成4-6個位元組。如果你要傳輸的文字包含大量英文字元,用UTF-8編碼就能節省空間:

在計算機記憶體中,統一使用Unicode編碼,當需要儲存到硬碟或者需要傳輸的時候,就轉換為UTF-8編碼,這樣可以節省很多儲存空間。

Python編碼

注:這裡討論的是python2.7的情況

兩個函式

在python中,str和unicode都是basestring的子類,basestring有以下兩個方法:

encode(): 將unicode字串轉換為其他編碼字串,引數為轉換後編碼

decode(): 將其他編碼轉換為unicode字串,引數為轉換前編碼

PS:"string".decode('utf-8') == unicode('string', 'utf-8')

一個栗子

結果是這樣的

console下檢視u2s

結論:

  • python中定義的一個str變數實則是位元組串,由Unicode經過編碼(encode)後的位元組組成的(
    也正好印證了utf8編碼中一箇中文字元是3個位元組)
  • Unicode才是真正意義上的字串,由字元組成

再次回顧兩個函式用法

新結論:不同編碼轉換,使用Unicode作為中間編碼

在Python 3.x版本中,把'xxx'u'xxx'已經都統一成Unicode編碼了,即寫不寫字首u都是一樣的,而以位元組形式表示的字串則必須加上b字首:b'xxx'

由於Python原始碼也是一個文字檔案,所以,當你的原始碼中包含中文的時候,在儲存原始碼時,就需要務必指定儲存為UTF-8編碼。當Python直譯器讀取原始碼時,為了讓它按UTF-8編碼讀取,我們通常在檔案開頭寫上這兩行:

參考

位元組、字、位、位元,這四者之間的關係
廖雪峰:python2.7教程之字串和編碼
PYTHON-進階-編碼處理小結

相關文章