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中的字符串概念,無(wú)法直接強(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庫(kù)解析,方法比較通用
- 用法
strcut.unpack(fmt, byte)
其中fmt為格式化字符串,分為兩部分,開(kāi)頭控制大小端,后面通過(guò)字符控制數(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碼是一種最常見(jiàn)的字符集,而為了表示漢字等還有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)⒅付ń馕鲎址?,但有的時(shí)候bytes流中可能包含不止一種字符集的數(shù)字,此時(shí)解析就會(huì)有問(wèn)題,如解析報(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())
通過(guò)s前指定數(shù)字來(lái)限定解析為ascii的byte范圍,這樣就對(duì)bytes中混合代表數(shù)字和代表ascii的字節(jié)做分別解析了
注意,strcut的s解析出認(rèn)為bytes類型,需要進(jìn)一步decode解析為str類型