gpt4 book ai didi

Python struct.unpack 不工作

转载 作者:太空狗 更新时间:2023-10-30 00:55:00 26 4
gpt4 key购买 nike

我正在尝试运行这个:

def ReadWord(fid,fmt,Addr):
fid.seek(Addr)
s = fid.readline(2)
s = unpack(fmt + 'h', s)
if(type(s) == tuple):
return s[0]
else:
return s

与:

len(s) = 2
len(fmt) = 1
calcsize(fmt) = 0
calcsize(fmt + 'h') = 2

但是,Python 返回:

struct.error: unpack requires a string argument of length 4

根据 python struct.unpack documentation :

The string must contain exactly the amount of data required by the format (len(string) must equal calcsize(fmt)).

因此,如果我的字符串的长度为 2 且计算大小为 fmt+'h'也是2,为什么python说“解包需要长度为4的字符串参数”??

编辑:

感谢您的所有回答。这是完整的代码:

http://qtwork.tudelft.nl/gitdata/users/guen/qtlabanalysis/analysis_modules/general/lecroy.py

正如您在 read_timetrace 中看到的那样功能,fmt设置为 '<''>'if...else陈述。打印它可以确认这一点。

但是您还应该知道我正在使用 windowsx64(工作)。

EDIT2

这是完整的回溯,对错误感到抱歉。

Traceback (most recent call last):
File "C:\Users\maxime.vast\Desktop\Test Campaign Template\Test Suite\Include\readLecroyTRCFile.py", line 139, in <module>
read_timetrace("C:\Users\maxime.vast\Desktop\Test Campaign Template\Test Suite\Traces\KL.ES.001.001.trc")
File "C:\Users\maxime.vast\Desktop\Test Campaign Template\Test Suite\Include\readLecroyTRCFile.py", line 60, in read_timetrace
WAVE_ARRAY_1 = ReadLong(fid, fmt, aWAVE_ARRAY_1)
File "C:\Users\maxime.vast\Desktop\Test Campaign Template\Test Suite\Include\readLecroyTRCFile.py", line 100, in ReadLong
s = unpack(fmt + 'l', s)
struct.error: unpack requires a string argument of length 4
[Finished in 0.2s]

编辑 3:

我替换了readline通过 read并添加:

print "len(s) ", len(s)
print "len(fmt) ", len(fmt)
print "calcsize(fmt) ", calcsize(fmt)
print "calcsize(fmt + 'h') ", calcsize(fmt + 'h')
print "fmt ", fmt

ReadLong功能。

这是新的追溯:

len(s)  4
len(fmt) 1
calcsize(fmt) 0
calcsize(fmt + 'h') 2
fmt <
len(s) 4
len(fmt) 1
calcsize(fmt) 0
calcsize(fmt + 'h') 2
fmt <
len(s) 4
len(fmt) 1
calcsize(fmt) 0
calcsize(fmt + 'h') 2
fmt <
len(s) 1
len(fmt) 1
calcsize(fmt) 0
calcsize(fmt + 'h') 2
fmt <
Traceback (most recent call last):
File "C:\Users\maxime.vast\Desktop\Test Campaign Template\Test Suite\Include\readLecroyTRCFile.py", line 143, in <module>
read_timetrace("C:\Users\maxime.vast\Desktop\Test Campaign Template\Test Suite\Traces\KL.ES.001.001.trc")
File "C:\Users\maxime.vast\Desktop\Test Campaign Template\Test Suite\Include\readLecroyTRCFile.py", line 60, in read_timetrace
WAVE_ARRAY_1 = ReadLong(fid, fmt, aWAVE_ARRAY_1)
File "C:\Users\maxime.vast\Desktop\Test Campaign Template\Test Suite\Include\readLecroyTRCFile.py", line 104, in ReadLong
s = unpack(fmt + 'l', s)
struct.error: unpack requires a string argument of length 4
[Finished in 0.2s]

最佳答案

FWIW,您应该使用 read(2),而不是 readline(2)。如果 fmt 字符串确实是 '>',您就不会收到该错误。这是一个按预期执行的简短演示。

from struct import unpack

fname = 'qbytes'

#Create a file of all byte values
with open(fname, 'wb') as f:
f.write(bytearray(range(256)))

def ReadWord(fid, fmt, addr):
fid.seek(addr)
s = fid.read(2)
s = unpack(fmt + 'h', s)
return s[0]

fid = open(fname, 'rb')

for i in range(16):
addr = i
n = 256*i + i+1
#Interpret file data as big-endian
print i, ReadWord(fid, '>', addr), n

fid.close()

输出

0 1 1
1 258 258
2 515 515
3 772 772
4 1029 1029
5 1286 1286
6 1543 1543
7 1800 1800
8 2057 2057
9 2314 2314
10 2571 2571
11 2828 2828
12 3085 3085
13 3342 3342
14 3599 3599
15 3856 3856

顺便说一句,struct.unpack()总是返回一个元组,即使返回值是单个项目也是如此。


对二进制文件使用 readline(2) 会产生意想不到的结果。在我上面代码的测试文件中,文件中有一个(Linux 风格的)换行符 \xa0。因此,如果您将 s = fid.read(2) 更改为 s = fid.readline(2) 一开始一切正常,但在第 10 行它崩溃了,因为它只由于换行符,读取单个字节:

from struct import unpack

fname = 'qbytes'

#Create a file of all byte values
with open(fname, 'wb') as f:
f.write(bytearray(range(256)))

def ReadWord(fid, fmt, addr):
fid.seek(addr)
s = fid.readline(2)
print repr(s),
s = unpack(fmt + 'h', s)
return s[0]

with open(fname, 'rb') as fid:
for i in range(16):
addr = i
n = 256*i + i+1
#Interpret file data as big-endian
print i, ReadWord(fid, '>', addr), n

输出

0 '\x00\x01' 1 1
1 '\x01\x02' 258 258
2 '\x02\x03' 515 515
3 '\x03\x04' 772 772
4 '\x04\x05' 1029 1029
5 '\x05\x06' 1286 1286
6 '\x06\x07' 1543 1543
7 '\x07\x08' 1800 1800
8 '\x08\t' 2057 2057
9 '\t\n' 2314 2314
10 '\n'
Traceback (most recent call last):
File "./qtest.py", line 30, in <module>
print i, ReadWord(fid, '>', addr), n
File "./qtest.py", line 22, in ReadWord
s = unpack(fmt + 'h', s)
struct.error: unpack requires a string argument of length 2

后记

您的代码中有几个函数几乎做同样的事情。这打破了 DRY原则:不要重复自己。这是解决该问题的一种方法,使用部分函数应用程序。查看functools docs了解更多信息。

from functools import partial

def ReadNumber(fid, datalen=1, fmt='>', conv='b', addr=0):
fid.seek(addr)
s = fid.read(datalen)
if len(s) != datalen:
raise IOError('Read %d bytes but expected %d at %d' % (len(s), datalen, addr))
return unpack(fmt+conv, s)[0]

ReadByte = partial(ReadNumber, datalen=1, conv='b')
ReadWord = partial(ReadNumber, datalen=2, conv='h')
ReadLong = partial(ReadNumber, datalen=4, conv='l')
ReadFloat = partial(ReadNumber, datalen=4, conv='f')
ReadDouble = partial(ReadNumber, datalen=8, conv='d')

您需要使用关键字来调用这些新功能。例如,

ReadLong(fid, fmt='>', addr=addr)

的确,这有点冗长,但它使代码更具可读性。

关于Python struct.unpack 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32519664/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com