淺談Python編碼

Python的編碼問題可能是很多人都遇到過的問題(沒遇到的終將會遇到的),筆者之前也對這個問題很模糊,今天看了《Effective Python》之後總結一下自己的理解。

Unicode

先看ASCII碼,ASCII碼我們比較熟悉,用一個字節表示了128個字符,其中包含標點符號,數字,英文字母等。

但是ASCII有一個問題,就是一個字節只有8位最多隻能表示256個字符,不可能表示世界各個國家的字符。於是有了Unicode碼。

Unicode碼(統一碼,萬國碼):用多個字節表示全世界的所有字符,爲每一個字符分配了一個唯一的標識(一個整數),在表示一個 Unicode 的字符時,通常會用“U+”然後緊接着一組十六進制的數字來表示這一個字符。

來自Wiki百科:在文字處理方面,統一碼爲每一個字符而非字形定義唯一的代碼(即一個整數)。換句話說,統一碼以一種抽象的方式(即數字)來處理字符,並將視覺上的演繹工作(例如字體大小、外觀形狀、字體形態、文體等)留給其他軟件來處理,例如網頁瀏覽器或是文字處理器。

UTF-8

UTF-8:由於Unicode只是給每一個字符分配了一個整數值,但是沒有規定如何存儲這個整數值(比如:用幾個字節存儲),所以需要utf-8等編碼。utf-8是一種將Unicode碼轉換成字節序列編碼方式,是一種可變長編碼。

可以這樣理解:

  • Unicode -> utf-8編碼 -> bytes
  • bytes -> utf-8解碼 -> Unicode

UTF-8只是Unicode與字節流編碼方式中的一種,還有UTF-16, GB-2312, GBK(windows系統的中文編碼是GBK)編碼等等。這些編碼做的工作就是將Unicode規定字符對應的整數值用一個或多個字節表示出來。

因爲IO,網絡數據傳輸都是通過字節流的方式,所以在編程時需要將Unicode碼轉換成字節流再進行傳輸;同樣需要將從IO,網絡接收到的字節流轉換成Unicode碼。

bytes、str與unicode

Python2和Python3的不同點之一就是編碼問題。其中str和unicode是Python2中的編碼,而bytes和str是Python3中的編碼。

Python2中的編碼:

  • str:bytes序列的字符串
  • unicode:unicode碼點序列 的字符串

Python3中的編碼:

  • bytes: bytes序列的字符串。
  • str: unicode碼點序列 的字符串。

讓人疑惑的是str,str在Python2和Python3中表示不同的編碼,Python2中表示字節序列,即bytes; Python3中表示Unicode碼。個人理解是Python3想讓在程序中定義的字符串使用Unicode碼錶示,而不是Python2中用字節流表示。

Python2

>>> string = "python"
>>> type(string)
<type 'str'>
>>> u_str = u"python"
>>> type(u_str)
<type 'unicode'>

Python3

>>> string = "python"
>>> bytes = b"python"
>>> type(string)
<class 'str'>
>>> type(bytes)
<class 'bytes'>

encode與decode

encode()和decode()是Python中用於bytes字節序列與Unicode序列轉換的函數。

  • unicode.encode() -> bytes:只有對於unicode對象我們才應該使用.encode()方法。這一方法用來將一系列unicode編碼爲bytes流。
  • bytes.decode() -> unicode: 只有對於bytes,或說Python2中的str對象,我們才應該調用.decode()方法。這一方法將一系列bytes流解碼爲原本的unicode碼點。

Python2

# str 與 unicode
>>> string = "python"
>>> type(string)
<type 'str'>
>>> u_str = u"python"
>>> type(u_str)
<type 'unicode'>

# str解碼 -> Unicode
>>> de_string = string.decode()
>>> type(de_string)
<type 'unicode'>

# unicode 編碼 -> str
>>> en_u_str = u_str.encode()
>>> type(en_u_str)
<type 'str'>

Python3

# str 與 bytes
>>> string = "python"
>>> bytes = b"python"
>>> type(string)
<class 'str'>
>>> type(bytes)
<class 'bytes'>

# str編碼 -> butes
>>> en_string = string.encode()
>>> type(en_string)
<class 'bytes'>

# bytes 解碼 -> str
>>> de_bytes = bytes.decode()
>>> type(de_bytes)
<class 'str'>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章