没有什么超光滑的,但是如果速度很重要,struct模块顶层函数是包装器,它们必须重复检查与格式字符串对应的实际struct.Struct实例的缓存;虽然必须创建单独的格式字符串,但可以通过避免重复的缓存检查来解决部分速度问题。在
而不是:buffer = memoryview(somedata)
allresults = []
while buffer:
allresults += struct.unpack_from('<10sHHb', buffer)
buffer = buffer[struct.calcsize('<10sHHb'):]
allresults += struct.unpack_from('>llh', buffer)
buffer = buffer[struct.calcsize('>llh'):]
你应该这样做:
^{pr2}$
不,它看起来不怎么好看,而且速度的提高也不太可能让你大吃一惊。但是你有奇怪的数据,所以这是最不脆弱的解决方案。在
如果您想要不必要的聪明/脆弱的解决方案,可以使用ctypes自定义Structures,在LittleEndianStructure中嵌套{},反之亦然。对于示例格式:from ctypes import *
class BEStruct(BigEndianStructure):
_fields_ = [('x', 2 * c_long), ('y', c_short)]
_pack_ = True
class MainStruct(LittleEndianStructure):
_fields_ = [('a', 10 * c_char), ('b', 2 * c_ushort), ('c', c_byte), ('big', BEStruct)]
_pack_ = True
你可以这样做:mystruct = MainStruct()
memoryview(mystruct).cast('B')[:] = bytes(range(25))
然后你会得到预期顺序的结果,例如:>>> hex(mystruct.b[0]) # Little endian as expected in main struct
'0xb0a'
>>> hex(mystruct.big.x[0]) # Big endian from inner big endian structure
'0xf101112'
虽然在某种程度上很聪明,但它很可能会运行得更慢(ctypes属性查找在我的经验中非常慢),而且与struct模块函数不同,您不能只在一行中解压到顶级命名变量中,而是一路进行属性访问。在