Python中的字符串編碼

前言

本人在使用Python2編寫腳本工具時,觀察到字符串其實有兩種形式,一種是不帶u,另外一種是帶u的。仔細查詢文檔發現內在細節還比較多,與Python3多有差別,特此筆記。python

Python2版本與Python3版本的差別之一,即編碼問題。在理解編碼以前,先介紹兩個概念。其中一個是字面量,另外一個是字節碼。網絡

在寫代碼時,咱們會定義字符串變量,用來表示一段文本內容。比方說 s="helloworld",這就是一個簡單的字面量。咱們也知道,代碼中的字符串變量,做爲操做數可能會用於網絡數據的交互,或者咱們會將這個內容存儲到持久存儲中。計算機的底層存儲數據本質上是0和1,那麼如何將這個字面量轉換成字節流的數據,就是對字面量的編碼。這也就是爲何目前會有這麼多種編碼方式,比方說utf-8gbkascii等。工具

那麼在Python2和Python3中,字面量和字節碼是以不一樣的類型來表示的,具體以下:編碼

版本 字節碼type 字面量type 默認編碼方式
Python2 str unicode ascii
Python3 byte Str utf-8

這裏咱們重點關注兩個方面,即字節碼和字面量的轉換,以及默認編碼方式帶來的影響。code

1.字節碼與字面量的轉換utf-8

總的來講,轉換關係是:ci

字節碼.encode(編碼格式)-->字面量unicode

字面量.decode(編碼格式)-->字節碼文檔

2.默認編碼方式的影響字符串

在Python3中使用utf-8做爲默認編碼,不會通過unicode編碼(utf-8是unicode一種變長類型),所以轉換主要在字面量和utf-8之間。

在Python2中相對來講會比較複雜,控制檯顯示的處理方式與Python3不一樣。第一點,因爲字面量是unicode類型,顯示的時候也是一個unicode編碼,沒有顯示字面量原本的樣子,但其實他們本質是同樣的。

# 這是在Python2中
>>> a = '深圳'
>>> a
u'\u6df1\u5733'

# 對比在Python3中,其實本質是同樣的
>>> '\u6df1\u5733'.encode('utf-8').decode('utf-8')
>>> ‘深圳’

第二點,Python2中的unicode字面量必需要顯示的帶u來表示,例如a=u'深圳'。若不帶u顯示錶示,則是一個str字節碼。

第三點,在Python3不能對字節碼byte進行encode操做,而在Python2中能夠對str進行encode操做。在Python2對字節碼變量執行encode動做時,默認會先decode成字面量,而後再使用給定編碼格式encode。這裏須要注意的是decode成字面量的過程是系統自動完成的,採用的是默認的編碼方式即ASCII。對於a='深圳'這樣一個含中文的字節碼來講,採用ASCII是沒法decode操做的(ASCII只能decode前255個字符),所以須要修改解釋器默認的編碼方式。

# 含中文字符,錯誤展現
>>> a = '深圳'
>>> a.encode('gbk')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)
  
# 純ASCII文本,能夠encode
>>> a = 'zimsky'
>>> a.encode('gbk')
'zimsky'
# 修改解釋器默認編碼方式
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
相關文章
相關標籤/搜索