perl unpack函数到python

时间:2018-03-22 14:03:20

标签: python perl unpack

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

我在翻译这一行时遇到了一些麻烦:

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

我在Pyhton尝试了这个

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

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

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

1 个答案:

答案 0 :(得分:3)

有两个问题,其中只有一个在Python 3中得到修复:

  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)