解決Python3 struct報錯argument for 's' must be a bytes object
錯誤
在用python3進行文件打包二進制數(shù)據(jù)的存儲與解析過程中使用struct模塊運行下面代碼發(fā)生錯誤:
F = open('data.bin', 'wb') import struct data = struct.pack('>i4sh', 7, 'spam', 8) data
報錯信息如下:
error Traceback (most recent call last)
<ipython-input-12-9b7a8e6cf48b> in <module>
1 F = open('data.bin', 'wb')
2 import struct
----> 3 data = struct.pack('>i6sh', 7, 'spam', 8)
4 data
?
error: argument for 's' must be a bytes object
先說解決方案:格式化字符串的值在python的類型是bytes類型,而python3中所有文本都是Unicode,所以需要轉(zhuǎn)換為bytes類型,在'spam'前面加’b'進行轉(zhuǎn)換。
F = open('data.bin', 'wb') import struct data = struct.pack('>i4sh', 7, b'spam', 8) data
輸出結(jié)果是:
b'\x00\x00\x00\x07spam\x00\x08'
python3新增的bytes類型
在python2中字節(jié)類型和字符類型區(qū)別不大,但是在python3中最重要的特性是對文本和二進制數(shù)據(jù)做了更加清晰的區(qū)分。
文本總是Unicode,由字符類型表示,而二進制數(shù)據(jù)則由bytes類型表示。
python3不會以任意隱式方式混用字節(jié)型和字符型,也因此在python3中不能拼接字符串和字節(jié)包(python2中可以,會自動進行轉(zhuǎn)換),也不能在字節(jié)包中搜索字符串,也不能將字符串傳入?yún)?shù)為字節(jié)包的函數(shù)。
需要注意的是,在網(wǎng)絡(luò)數(shù)據(jù)傳輸過程中,python2可以通過字符串(string)方式傳輸,但是python3只能通過二進制(bytes)方式來傳輸,因此要對傳輸文本進行轉(zhuǎn)換。
轉(zhuǎn)化方式:
str → byte 用encode()方法 byte → str 用decode()方法
中文字符串轉(zhuǎn)二進制:
'你好'.encode('utf-8')
輸出:
b'\xe4\xbd\xa0\xe5\xa5\xbd'
二進制轉(zhuǎn)回字符串:
b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode('utf-8')
輸出:'你好'
英文字符串轉(zhuǎn)二進制
'hello world'.encode('utf-8')
輸出:
b'hello world'
encode()和decode()方法中默認(rèn)編碼為utf-8,但是為了避免錯誤,最好將編碼加上。
僅僅知道加'b'可以解決問題但是感覺還是不夠,'>i4sh'看不懂,所以去官方文檔查struct看到結(jié)果如下:
struct.pack(format, v1, v2, ...) 返回一個 bytes 對象,其中包含根據(jù)格式字符串 format 打包的值 v1, v2, ... 參數(shù)個數(shù)必須與格式字符串所要求的值完全匹配。
可以看出i對應(yīng)的是python中的整數(shù),s對應(yīng)的是字符串,h對應(yīng)的是整數(shù)。
格式字符之前可以帶有整數(shù)重復(fù)計數(shù)。 例如,格式字符串 '4h'
的含義與 'hhhh'
完全相同。
所以測試了一下,在h前加數(shù)字2:
F = open('data.bin', 'wb') import struct data = struct.pack('>i4s2h', 7, b'spam', 8) data
報錯如下:
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-33-a27281e58db6> in <module>
1 F = open('data.bin', 'wb')
2 import struct
----> 3 data = struct.pack('>i4s2h', 7, b'spam', 8)
4 data
?
error: pack expected 4 items for packing (got 3)
也是就說2h就需要在s后面有2個整數(shù)參數(shù),但是'4s'卻不是需要四個bytes參數(shù)。
對于 's' 格式字符,計數(shù)會被解析為字節(jié)的長度,而不是像其他格式字符那樣的重復(fù)計數(shù);例如,'10s' 表示一個 10 字節(jié)的字節(jié)串,而 '10c' 表示 10 個字符。 如果未給出計數(shù),則默認(rèn)值為 1。 對于打包操作,字節(jié)串會被適當(dāng)?shù)亟財嗷蛱畛淇兆止?jié)以符合要求。
所以做了個測試,先后將s前的數(shù)字從1慢慢漲到6得到的輸出結(jié)果如下:
b'\x00\x00\x00\x07s\x00\x08' #'>i1sh'
b'\x00\x00\x00\x07sp\x00\x08' #'>i2sh'
b'\x00\x00\x00\x07spa\x00\x08' #'>i3sh'
b'\x00\x00\x00\x07spam\x00\x08' #'>i4sh'
b'\x00\x00\x00\x07spam\x00\x00\x08' #'>i5sh'
b'\x00\x00\x00\x07spam\x00\x00\x00\x08' #'>i6sh'
在數(shù)字小于后面字節(jié)長度時會截取,超過長度時會在后面填充空字節(jié)。
以上就是解決Python3 struct報錯argument for 's' must be a bytes object的詳細(xì)內(nèi)容,更多關(guān)于Python3 struct報錯解決的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Python pandas讀取CSV文件應(yīng)該注意什么?
本文是給使用pandas的新手而寫,主要列出一些常見的問題,根據(jù)筆者所踩過的坑,進行歸納總結(jié),希望對讀者有所幫助,需要的朋友可以參考下2021-06-06如何利用Python和matplotlib更改縱橫坐標(biāo)刻度顏色
對于圖表來說最簡單的莫過于作出一個單一函數(shù)的圖像,下面這篇文章主要給大家介紹了關(guān)于如何利用Python和matplotlib更改縱橫坐標(biāo)刻度顏色的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08flask-socketio實現(xiàn)WebSocket的方法
這篇文章主要介紹了flask-socketio實現(xiàn)WebSocket的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07Python實現(xiàn)按照指定要求逆序輸出一個數(shù)字的方法
這篇文章主要介紹了Python實現(xiàn)按照指定要求逆序輸出一個數(shù)字的方法,涉及Python針對字符串的遍歷、判斷、輸出等相關(guān)操作技巧,需要的朋友可以參考下2018-04-04django 連接數(shù)據(jù)庫出現(xiàn)1045錯誤的解決方式
這篇文章主要介紹了django 連接數(shù)據(jù)庫出現(xiàn)1045錯誤的解決方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05總結(jié)用Pdb庫調(diào)試Python的方式及常用的命令
大家都知道Python是自帶Pdb庫,使用Pdb調(diào)試Python程序還是很方便的。但是遠(yuǎn)程調(diào)試、多線程,Pdb是搞不定的,下面一起來看看用Pdb庫調(diào)試Python的方式及常用的命令。2016-08-08深入了解Python中字符串格式化工具f-strings的使用
從Python?3.6版本開始,引入了一種新的字符串格式化機制,即f-strings,它強大且易于使用的字符串格式化方式,本文就來聊聊他的具體使用,希望對大家有所幫助2023-05-05