一 在python2中有兩種字符串類型str和unicode
str類型
當(dāng)python解釋器執(zhí)行到產(chǎn)生字符串的代碼時(例如x='上'),會申請新的內(nèi)存地址,然后將'上'編碼成文件開頭指定的編碼格式
要想看x在內(nèi)存中的真實格式,可以將其放入列表中再打印,而不要直接打印,因為直接print()會自動轉(zhuǎn)換編碼,這一點我們稍后再說。
#coding:gbk
x='上'
y='下'
print([x,y]) #['\xc9\xcf', '\xcf\xc2']
#\x代表16進制,此處是c9cf總共4位16進制數(shù),一個16進制四4個比特位,4個16進制數(shù)則是16個比特位,即2個Bytes,這就證明了按照gbk編碼中文用2Bytes
print(type(x),type(y)) #(<type 'str'>, <type 'str'>)
理解字符編碼的關(guān)鍵!!!
內(nèi)存中的數(shù)據(jù)通常用16進制表示,2位16進制數(shù)據(jù)代表一個字節(jié),如\xc9,代表兩位16進制,一個字節(jié)
gbk存中文需要2個bytes,而存英文則需要1個bytes,它是如何做到的???!!!
gbk會在每個bytes,即8位bit的第一個位作為標志位,標志位為1則表示是中文字符,如果標志位為0則表示為英文字符
x=‘你a好’
轉(zhuǎn)成gbk格式二進制位
8bit+8bit+8bit+8bit+8bit=(1+7bit)+(1+7bit)+(0+7bit)+(1+7bit)+(1+7bit)
這樣計算機按照從左往右的順序讀:
#連續(xù)讀到前兩個括號內(nèi)的首位標志位均為1,則構(gòu)成一個中午字符:你
#讀到第三個括號的首位標志為0,則該8bit代表一個英文字符:a
#連續(xù)讀到后兩個括號內(nèi)的首位標志位均為1,則構(gòu)成一個中午字符:好
也就是說,每個Bytes留給我們用來存真正值的有效位數(shù)只有7位,而在unicode表中存放的只是這有效的7位,至于首位的標志位與具體的編碼有關(guān),即在unicode中表示gbk的方式為:
(7bit)+(7bit)+(7bit)+(7bit)+(7bit)
按照上圖翻譯的結(jié)果,我們可以去unicode關(guān)于漢字的對應(yīng)關(guān)系中去查:
鏈接:https://pan.baidu.com/s/1dEV3RYp
可以看到“”上“”對應(yīng)的gbk(G0代表的是gbk)編碼就為494F,即我們得出的結(jié)果,而上對應(yīng)的unicode編碼為4E0A,我們可以將gbk-->decode-->unicode
#coding:gbk
x='上'.decode('gbk')
y='下'.decode('gbk')
print([x,y]) #[u'\u4e0a', u'\u4e0b']
unicode類型
當(dāng)python解釋器執(zhí)行到產(chǎn)生字符串的代碼時(例如s=u'林'),會申請新的內(nèi)存地址,然后將'林'以unicode的格式存放到新的內(nèi)存空間中,所以s只能encode,不能decode
#coding:gbk
x=u'上' #等同于 x='上'.decode('gbk')
y=u'下' #等同于 y='下'.decode('gbk')
print([x,y]) #[u'\u4e0a', u'\u4e0b']
print(type(x),type(y)) #(<type 'unicode'>, <type 'unicode'>)
打印到終端
對于print需要特別說明的是:
當(dāng)程序執(zhí)行時,比如
x='上' #gbk下,字符串存放為\xc9\xcf
print(x) #這一步是將x指向的那塊新的內(nèi)存空間(非代碼所在的內(nèi)存空間)中的內(nèi)存,打印到終端,按理說應(yīng)該是存的什么就打印什么,但打印\xc9\xcf,對一些不熟知python編碼的程序員,立馬就懵逼了,所以龜叔自作主張,在print(x)時,使用終端的編碼格式,將內(nèi)存中的\xc9\xcf轉(zhuǎn)成字符顯示,此時就需要終端編碼必須為gbk,否則無法正常顯示原內(nèi)容:上
對于unicode格式的數(shù)據(jù)來說,無論怎么打印,都不會亂碼
unicode這么好,不會亂碼,那python2為何還那么別扭,搞一個str出來呢?python誕生之時,unicode并未像今天這樣普及,很明顯,好的東西你能看得見,龜叔早就看見了,龜叔在python3中將str直接存成unicode,我們定義一個str,無需加u前綴,就是一個unicode,屌不屌?
二 在python3 中也有兩種字符串類型str和bytes
str是unicode
#coding:gbk
x='上' #當(dāng)程序執(zhí)行時,無需加u,'上'也會被以unicode形式保存新的內(nèi)存空間中,
print(type(x)) #<class 'str'>
#x可以直接encode成任意編碼格式
print(x.encode('gbk')) #b'\xc9\xcf'
print(type(x.encode('gbk'))) #<class 'bytes'>
很重要的一點是:看到python3中x.encode('gbk') 的結(jié)果\xc9\xcf正是python2中的str類型的值,而在python3是bytes類型,在python2中則是str類型
于是我有一個大膽的推測:python2中的str類型就是python3的bytes類型,于是我查看python2的str()源碼,發(fā)現(xiàn)