pack格式字符串中的autorepeat标志

2024-03-29 07:57:48 发布

您现在位置:Python中文网/ 问答频道 /正文

在php中,unpack()有一个“*”标志,意思是“重复此格式直到输入结束”。例如,这将打印97、98、99

$str = "abc";
$b = unpack("c*", $str);
print_r($b);

python中有类似的东西吗?当然,我可以

^{pr2}$

但我想知道有没有更好的方法。在


Tags: 方法标志格式phpabcprintstrunpack
2条回答

struct.unpack中没有这样的功能,但是可以定义这样一个函数:

import struct

def unpack(fmt, astr):
    """
    Return struct.unpack(fmt, astr) with the optional single * in fmt replaced with
    the appropriate number, given the length of astr.
    """
    # http://stackoverflow.com/a/7867892/190597
    try:
        return struct.unpack(fmt, astr)
    except struct.error:
        flen = struct.calcsize(fmt.replace('*', ''))
        alen = len(astr)
        idx = fmt.find('*')
        before_char = fmt[idx-1]
        n = (alen-flen)/struct.calcsize(before_char)+1
        fmt = ''.join((fmt[:idx-1], str(n), before_char, fmt[idx+1:]))
        return struct.unpack(fmt, astr)

print(unpack('b*','abc'))
# (97, 98, 99)

在Python3.4和更高版本中,可以使用新函数^{}。在

struct.iter_unpack(fmt, buffer)

Iteratively unpack from the buffer buffer according to the format string fmt. This function returns an iterator which will read equally-sized chunks from the buffer until all its contents have been consumed. The buffer’s size in bytes must be a multiple of the size required by the format, as reflected by calcsize().

Each iteration yields a tuple as specified by the format string.

假设我们要用重复格式字符串'<2sc'(2个字符后跟一个字符,重复直到完成)来解压数组{}。在

使用iter_unpack,可以执行以下操作:

>>> import struct
>>> some_bytes = b'\x01\x02\x03'*3
>>> fmt = '<2sc'
>>> 
>>> tuple(struct.iter_unpack(fmt, some_bytes))
((b'\x01\x02', b'\x03'), (b'\x01\x02', b'\x03'), (b'\x01\x02', b'\x03'))

如果要取消嵌套此结果,可以使用^{}执行此操作。在

^{pr2}$

当然,您可以使用嵌套的理解来做同样的事情。在

>>> tuple(x for subtuple in struct.iter_unpack(fmt, some_bytes) for x in subtuple)
(b'\x01\x02', b'\x03', b'\x01\x02', b'\x03', b'\x01\x02', b'\x03')

相关问题 更多 >