我正在阅读一个python代码库,我对此声明感到困惑:
struct.pack( "<ii%ds"%len(value), ParameterTypes.String, len(value), value.encode("UTF8") )
我理解除%d
以外的所有内容,而且我不确定为什么value
的长度被打包两次。
据我了解,该结构将具有很少的字节序编码(<
)并且将包含两个整数(ii
),后跟%d,后跟一个字符串(s
)
%d
有什么意义?
答案 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"))
现在让我们假设value
是u'\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'