您好,登錄后才能下訂單哦!
本篇內容主要講解“python編碼的原理及使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“python編碼的原理及使用”吧!
編碼就是為了解決字符和字節之間的關系。
分字符和字節是為了解決人機之間的關系,一般人只能讀字符,機器只能識別字節。
字符'a',人能夠識別,機器不能識別,機器只能識別字節。
所以需要一種把字符'a'轉換為字節的技術。
這種技術就是編碼,例如我們最常見的ASCII(American Standard Code for Information Interchange)碼,就包含英文字符數字和一些控制字符。
我們通過ASCII碼表就可以找到字符'a'對應的數字為97,這樣我們就可以把字符'a'通過編碼轉換為二進制字節01100001,這樣機器就能識別了。
我們一般說的編碼,指字符集和字符集中字符對應的值,而不是編碼方式
一般的編碼方式就是字符集中字符的編碼對應的二進制
Unicode字符集有所不同,有多種常用的編碼方式,后面詳細介紹。
因為有不同的人,使用了不同的字符,如中國人使用了中文字符,正如你現在讀到的字符一樣,我們在ASCII碼表中是找不到對應字符的,自然也不能根據ASCII把字符轉換為字節。
所以我們自己就需要新的編碼方式,來包含我們自己的字符,從最開始的GB2312到GBK,再到GB18030。
同理,其他語言也有自己對應的字符集和編碼。
在國際化的進程中,只玩自己的編碼肯定是不行的,所以需要統一的編碼,就是包含世界字符,這樣只需要在應用中使用Unicode碼,就能避免為應用做適配。
我們知道編碼是包含字符集和字符集中字符對應的值,一般字符集和對應的值放在一起做為一個對應編碼的碼表。
Unicode有2個字符集,UCS-2和UCS-4,因為UCS-4兼容UCS-2,所以這里介紹一下UCS-4。
UCS-4使用4字節編碼,最高位都是0,所以最高字節的8位有7位有效位。
UCS-4使用最高字節的7位來標識組(group),也就是有2^7=128個組。
UCS-4使用次高字節來標識平面(plane),8位共2^8=256個平面。
UCS-4使用第3字節來標識行(row),8位2^8=256行。
UCS-4使用第4字節來標識碼位(cell),同理有256個碼位。
group 0的plane 0被稱作Basic Multilingual Plane(BMP)
UCS-4中,高兩個字節為0的碼位被稱作BMP,BMP去掉2個全為0的高字節之后,就是2字節的UCS-2。
通過上面的介紹我們很容易算出:UCS-2共有2^16=65536個碼位。
這也是在python2.x中:
import sys print sys.maxunicode
打印的值是65535的原因(從0開始,所以最大碼位是65535)。
Unicode計劃使用了17個平面,每個平面65536個碼位,共有17×65536=1114112個碼位。
這也是在python3.x中:
import sys print sys.maxunicode
打印的值是1114111的原因
先介紹一下'中文'這2個字符的相關編碼:
'中文'的Unicode編碼:\u4e2d\u6587 '中文'的UTF-8編碼:\xe4\xb8\xad\xe6\x96\x87 '中文'的GBK編碼:\xd6\xd0\xce\xc4
下面代碼不是通過交互程序,而是寫入文件,在cmd執行。
print("中文")
加入有文件名為test-encoding.py的文件內容如上所示,我們在中文環境windows下執行該文件,就會得到下面的錯誤。
我們可以通過查看test-encoding.py文件的16進制,可以看出test-encoding.py文件使用的是UTF-8編碼,對比'中文'的編碼得出。
我們也可以看出這不是一個執行時候的錯誤,因為這是一個SyntaxError,說明是一個語法錯誤。
同時這個錯誤也告訴了我們原因,是因為有非ASCII字符,因為python默認的編碼是ASCII,所以不能包含有非ASCII字符。
需要包含非ASCII字符我們需要一點特殊的處理,就是告訴python解釋器,文件使用的編碼方式。
# -*- coding: utf-8 -*- print("中文")
添加的注釋部分是告訴python解釋器使用utf-8方式做為字符與字節之間的編碼方式。
告訴解釋器使用utf-8編碼就夠了嗎?
顯然不是,因為還涉及到其他的編碼方式,例如我們在cmd中執行上面的文件,會得到輸出
涓枃
上面的輸出值其實就是'中文'這2個字符的UTF-8編碼\xe4\xb8\xad\xe6\x96\x87對應的GBK編碼。 可以自己對照GBK碼表檢查,也可以使用在線轉換編碼工具轉換驗證。
因為windows默認的代碼頁是936,也就是GBK編碼。
可以通過下面的2中方式解決:
# -*- coding: utf-8 -*- print(u"中文") print(a.decode('utf-8').encode('gbk'))
python2.x默認的編碼是ASCII python3.x默認的編碼是UTF-8
可以通過sys.getdefaultencoding()查看默認編碼方式
那么默認的編碼方式到底是什么?
在有些風騷的操作中,可能會教你使用下面的方式解決亂碼:
# -*- coding: utf-8 -*- import sys print(sys.getdefaultencoding()) reload(sys) sys.setdefaultencoding('utf-8') print(sys.getdefaultencoding()) a = '中文' print(a)
然而這并沒有什么用,因為這是輸出端的問題
那這個騷操作在什么地方有用呢?
答案是處理unicode的時候:
# -*- coding: utf-8 -*- import sys print(sys.getdefaultencoding()) # reload(sys) # sys.setdefaultencoding('utf-8') with open(r'F:\tmp\test.txt', 'w') as f: f.write('測試') f.write(u'測試')
執行上面的代碼,會得到下面的錯誤(2.x):
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
但是把注釋代碼取消注釋,就沒有問題了。
我們來分析一下: f.write(str)接收的是一個str類型的參數,u'測試'是一個unicode類型。
unicode到str需要encode,字節和字符之間的轉換是需要編碼的,顯然這里使用的是:
u'測試'.encode(sys.getdefaultencoding())
python 交互式使用的編碼默認會讀取系統的編碼,中文環境下windows下一般是GBK。
所以我們使用交互式的方式一般是沒有亂碼的問題。
UnicodeEncodeError: 'gbk' codec can't encode character u'\xa0' in position 392477: illegal multibyte sequence
有時候會遇到上面的錯誤,出現這個錯誤的原因基本都是因為有輸出到cmd的命令,也就是基本是因為print('xxx')造成的,其中xxx是GBK不兼容的字符。
其實我們可以很容易的構造一個類似的錯誤出來(2.x):
print('?'.decode("utf-8")) #print('?'.decode("utf-8").encode("gbk"))
在中文環境下的windows命令行執行包含上面代碼的文件就會看到UnicodeEncodeError錯誤。
Unicode編碼中: 基本漢字范圍:4E00-9FA5(20902個) 基本漢字補充:9FA6-9FEF(74個) ?的Unicode碼是:9FA6,GBK中是沒有包含?這個字的
解決辦法: 出現這個錯誤,就說明包含有超出GBK范圍的字符了,所以就不要使用GBK編碼方式了。
中文windows命令行默認GBK,不修改代碼頁肯定有這個問題,只有修改代碼頁才能解決。
換種思路直接輸出到文件,使用UTF-8編碼不是挺好的。
#a是字符串(str)類型 a = '中文' #b是unicode類型 b = u'中文'
2者的不同之處在于:
str類型使用的是系統默認編碼(可設置)
unicode的類型使用的是unicode的編碼
轉換: str通過decode可以獲取到unicode類型 unicode的通過encode得到str類型
2.x默認使用的是ASCII做字符與字節之間的編碼轉換,使用的字符集是UCS-2。
因為2.x沒有byte類型,所以不同編碼之間要轉換先存儲為unicode編碼,然后需要什么編碼,再從unicode編碼轉換為對應的編碼。
相比于2.x,3.x版本就正常多了,和其他語言的邏輯保持了一致性。
首先最重要的是添加了byte類型,即字節類型。
不再顯示的使用unicode編碼,而是遵從:
字符<--->編碼<--->字節
#字符--->編碼--->字節 bs = "中文".encode('utf-8') #字節--->編碼--->字符 ch = bs.decode("utf-8")
3.x默認使用utf-8做字節和字符之間轉換的編碼方式,使用的字符集是UCS-4。
亂碼說明字節-->字符的編碼出問題了。
所以首先得弄清楚文件、網絡中的字節使用的是什么編碼方式,是ASCII、GBK、UTF-8……
然后得弄清楚輸出字符的終端、編輯器是什么編碼,然后對應起來: decode、encode配對使用一樣的編碼就可以了。
有些朋友可能會說,這不是廢話嗎?我知道是什么編碼,還會亂碼?
問題的重點在于:字節從哪里來,顯示字符的編輯器或終端使用什么編碼。這樣至少可以定位大多數問題。
至于中間經過多次轉換的,那就需要仔細排查了。
到此,相信大家對“python編碼的原理及使用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。