Struct.unpack和字节对象的长度
我有以下代码(data是一个字节对象):
v = sum(struct.unpack('!%sH' % int(len(data)/2), data))
让我感到困惑的是格式字符串中的%sH和% int(len(data)/2
这部分代码到底是怎么工作的?字节对象的长度是什么?这到底是在求什么的和呢?
2 个回答
1
你的代码是怎么工作的:
- 你在解析
data
的字节结构struct.unpack
用一个字符串来告诉你想要解析的数据的字节格式- 根据这个格式,
struct.unpack
会返回一个可迭代的解析结果。
- 然后你对这个可迭代的结果进行求和。
字节格式化
为了解析你传入的数据,你需要创建一个 字符串 来告诉 Python 数据的格式。具体来说,%sH
这个部分是用来表示 这个数量的无符号短整型,然后你可以格式化它,说明你想要的 unsigned short
的确切数量。
在这个例子中,数量是:
int(len(data) / 2)
因为一个 unsigned short
通常是 2 个字节宽。
5
假设你有一个字节串 data
,比如:
>>> data = b'\x01\x02\x03\x04'
>>> data
'\x01\x02\x03\x04'
这个字节串的长度就是里面的字节(或字符)数量:
>>> len(data)
4
所以这段代码和你的代码是等价的:
>>> import struct
>>> struct.unpack('!2H', data)
(258, 772)
这段代码告诉 struct
模块使用以下的 格式字符:
!
- 使用网络(大端)模式2H
- 解包两个无符号短整型(每个16位)
这样就会返回两个整数,这两个整数对应你提供的数据:
>>> '%04x' % 258
'0102'
>>> '%04x' % 772
'0304'
你的代码的作用就是自动计算出无符号短整型的数量
>>> struct.unpack('!%sH' % int(len(data)/2), data)
(258, 772)
不过,int
转换其实是多余的,而且不应该使用 %s
这个占位符,因为它是用来替换字符串的:
>>> struct.unpack('!%dH' % (len(data)/2), data)
(258, 772)
所以解包的结果会返回两个整数,这两个整数是从字节串中解包出的两个无符号短整型的值。然后,求和操作会返回这两个整数的和:
>>> sum(struct.unpack('!%dH' % (len(data)/2), data))
1030