%d在struct.pack中的含义是什么?

时间:2010-08-18 09:49:35

标签: python struct

我正在阅读一个python代码库,我对此声明感到困惑:

struct.pack( "<ii%ds"%len(value), ParameterTypes.String, len(value), value.encode("UTF8") )

我理解除%d以外的所有内容,而且我不确定为什么value的长度被打包两次。

据我了解,该结构将具有很少的字节序编码(<)并且将包含两个整数(ii),后跟%d,后跟一个字符串(s

%d有什么意义?

5 个答案:

答案 0 :(得分:2)

Aarrrgh心灵难以置信......

@ S.Lott:“”“我不认为这个数字特别重要,因为如果没有它,Python将倾向于正确打包。”“” -1 。不要想;调查。没有数字意味着数字默认为1.趋于正确包装???也许您认为struct.pack("s", foo)"%s" % foo的工作方式相同?它没有; docs说“”“对于's'格式字符,计数被解释为字符串的大小,而不是像其他格式字符一样的重复计数;例如,'10s'表示单个10字节字符串,而'10c'表示10个字符。对于打包,字符串被截断或用空字节填充,以使其适合。“”“

@Brendan: -1 value不是数组(无论是什么);很明显,它显然是一个unicode字符串......在这里lookee:value.encode("UTF8")

@Matt Ellen:您引用的代码行严重破坏。如果value中有任何非ASCII字符,数据将会丢失。

让我们分解一下:

`struct.pack("<ii%ds"%len(value), ParameterTypes.String, len(value), value.encode("UTF8"))`  

删除第一项

以减少问题空间

struct.pack("<i%ds"%len(value), len(value), value.encode("UTF8"))

现在让我们假设valueu'\xff\xff',所以len(value)是2.

v8 = value.encode('UTF8'),即'\xc3\xbf\xc3\xbf'

请注意len(v8)是4.便士一分钱了吗?

所以我们现在拥有的是

struct.pack("<i2s", 2, v8)

数字2打包为4个字节02 00 00 00。 4字节字符串v8是TRUNCATED(在“2s”中长度为2)到长度为2。数据丢失。 FAIL。

正确想要做的事情的正确方法是:

v8 = value.encode('UTF8')
struct.pack("<ii%ds" % len(v8), ParameterTypes.String, len(v8), v8)

答案 1 :(得分:1)

这是一个普通的string format,用于创建结构格式

尝试将其作为普通字符串开始阅读(暂时忘记struct)...

"<ii%ds" % len(value)

例如,如果值iterable的长度为4,则字符串为<ii4s。然后将其传递给struct.pack,准备打包两个整数,后跟一个长度为4个字节的字符串,来自value可迭代

答案 2 :(得分:0)

%d表示分两步工作。

第1步。

"<ii%ds"%len(value) 

创建"<ii...some number...s"

的结构格式字符串

第2步。

生成的格式字符串应用于三个值

ParameterTypes.String, len(value), value.encode("UTF8")

答案 3 :(得分:0)

它用于指定在这两个整数之后打包value个字符的字符串(len(value))。

例如,如果value包含"boo",那么pack的实际格式说明符将为"<ii3s"

答案 4 :(得分:0)

%d的重要性在于它是字符串的格式参数:
String Formatting Operations

如果分手,"<ii%ds" % len(value)会更容易理解。它正在使用len(value)的返回值替换字符串中的%d转换指标,适当地进行类型转换。

>>> str = "<ii%ds"
>>> str % 5
'<ii5s'
>>> str % 3
'<ii3s'