perl 解压函数到 python

perl unpack function to python

我正在尝试将 Perl 脚本翻译成 Python。

我在翻译这行时遇到了一些问题:

my ($sync,$pid,$afccc,@bytes)=unpack('CnCC*',$pkt);

我在 Python

中试过了
bytes=[]
sync,pid,afccc,bytes=struct.unpack_from('BHBB',pkt)

但是此行之后的可变字节不是列表,则执行失败。

仅供参考,pkt 是一个 188 个字符长的字符串。

有两个问题,Python3 中只修复了一个:

  1. struct.unpack不支持任意重复。 (Python 3.4 引入了 iter_unpack,但这在这里并没有真正帮助。)你需要一个确切的 为每个说明符计数。你不能写 'BHB*B';相反,您需要计算 BHB 之后预期的字节数。幸运的是,做起来并不难或难看:

    header_fmt = struct.Struct('BHB')
    packet_fmt = struct.Struct(header_fmt.format +
                               '{}B'.format(188 - header_fmt.size))
    # packet_fmt.format == 'BHB183B'
    

    (通常您可能需要使用 len(pkt) 而不是硬编码 188。)

    'BHB*B',虽然会很好。

  2. 在 Python 2 中,您必须显式地从数组中提取尾随字节:

    fields = packet_fmt.unpack(pkt)
    sync, pid, afccc = fields[3:]
    bytes = fields[3:]
    

    或者,您可以使用 unpack_from 和拼接,因为您不需要像提取字节那样解压字节。

    sync, pid, afccc = header_fmt.unpack_from(pkt)
    bytes = pkt[header_fmt.size:]
    

    在 Python 3 中,您可以只使用 *name 语法来解包元组。

    sync, pid, afccc, *bytes = packet_fmt.unpack(pkt)