bytes類型解釋
python中的bytes類型可以類比為C中的uint8型數(shù)組,本質(zhì)就是順序排列的8bit二進(jìn)制數(shù)字褥符,例如以二進(jìn)制方式從文件中讀取時(shí)返回的就是bytes類型,或以b前綴的字符串也是bytes類型韭寸,如
a = b'abcd'
print(type(a))
返回<class 'bytes'>
bytes類型與ascii碼春哨、str類型區(qū)別
bytes類型非常容易和ascii碼以及str類型混淆,我也中間被繞暈幾次恩伺,現(xiàn)在整理如下
- bytes類型和ascii碼
import sys
b = b'\x61\x62\x63\x64' #代表兩個(gè)beyte的16進(jìn)制數(shù)字赴背,分別是0x61 0x62 0x63 0x64 即97~100
b = b'abcd' #代表abcd的ascii碼對(duì)應(yīng)的4個(gè)1byte數(shù)字,分別是97晶渠、98凰荚、99、100
for i in b:
print(b) # 97 98 99 100
print(a==b) #True
bytes只是一個(gè)8bit數(shù)字為一個(gè)單位元素的數(shù)組褒脯,而ascii是解析這樣一個(gè)數(shù)字?jǐn)?shù)組的解碼方式便瑟,類似的還有utf-8等
- bytes類型與str類型
b = b'abcd'
print(b[0]) #97
print(int(b[0]) #97
s = 'abcd' #并不代表內(nèi)存中是按abcd的ascii碼存儲(chǔ)的!str實(shí)際是一個(gè)對(duì)象而不是一個(gè)簡(jiǎn)單數(shù)組
print(int(s[0])) #error 因?yàn)閟tr類型的每個(gè)元素不是一個(gè)簡(jiǎn)單數(shù)字憨颠!
str是一個(gè)對(duì)象類型胳徽,不是C中的字符串概念,無法直接強(qiáng)轉(zhuǎn)為數(shù)字
bytes類型就是最基本的"code"爽彤,即連續(xù)的二進(jìn)制數(shù)字养盗,而對(duì)bytes類型做不同的”解釋“, 按照ascii碼解析得到了str,按照utf-8解析适篙,可以得到更多字符表示
bytes類型的解析
bytes類型的解析可以分為兩類往核,一類是解析為數(shù)字類型,一類是解析為文本
bytes解析為數(shù)字
主要分為解析為 UINT8嚷节、UINT16聂儒、UINT32、UINT64等數(shù)字類型硫痰,即分別對(duì)應(yīng)將每1衩婚、2、4效斑、8個(gè)字節(jié)放一起解釋為一個(gè)數(shù)字非春,這其中對(duì)于多于一個(gè)字節(jié)的情況又分大小端處理
推薦使用自帶的struct庫解析,方法比較通用
- 用法
strcut.unpack(fmt, byte)
其中fmt為格式化字符串缓屠,分為兩部分奇昙,開頭控制大小端,后面通過字符控制數(shù)字類型敌完,常用如下
fmt | 含義 |
---|---|
i | 大端序储耐,和>相同 |
> | 大端序 |
< | 小端序 |
B | uint8類型 |
b | int8類型 |
H | uint16類型 |
h | int16類型 |
I | uint32類型 |
i | int32類型 |
L | uint64類型 |
l | int64類型 |
s | ascii碼,s前帶數(shù)字表示個(gè)數(shù) |
更多詳細(xì)fmt的用法可用help(strcut)
- 例子
import struct
m = b'\x01\x01\x02\x01\x02\x03\x04' #7個(gè)字節(jié)
a=struct.unpack('!BHI', m)
for i in a:
print(hex(i)) # 0x1 0x102 0x1020304
bytes解析為文本
文本最終是屬于某一種字符集的滨溉,ascii碼是一種最常見的字符集什湘,而為了表示漢字等還有utf-8以及unicode等字符集长赞,從bytes解析到文本常用兩種方法
- decode方法(通用)
b = b'\x61\x62'
b2=b'\xe4\xbd\xa0\xe5\xa5\xbd'
print(b.decode('ascii')) #a b
print(b2.decode('utf-8')) #你好
errb = b'\x80\x61'
print(errb.decode('ascii')) #error! 0x80不是ascii字符集的元素禽炬!
bytes類型自帶的decode方法即可涧卵,入?yún)⒅付ń馕鲎址械臅r(shí)候bytes流中可能包含不止一種字符集的數(shù)字腹尖,此時(shí)解析就會(huì)有問題,如解析報(bào)文流的時(shí)候
- struct方法(解析ascii)
import struct
b= b'\x80\x61'
m=struct.unpack('!B1s', b)
for i in m:
print(m) # 0x80, b'a'
print(m[1].decode())
通過s前指定數(shù)字來限定解析為ascii的byte范圍伐脖,這樣就對(duì)bytes中混合代表數(shù)字和代表ascii的字節(jié)做分別解析了
注意热幔,strcut的s解析出認(rèn)為bytes類型,需要進(jìn)一步decode解析為str類型