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