Skip to main content
 首页 » 编程设计

Python Construct之为可选字段使用数据

2025年05月04日9jyk

使用 Python construct库,我正在解析的数据有一个字段,只有在设置标志时才有意义。

但是,数据字段始终存在。

因此,无论如何我都想消费数据,但只根据标志的值设置字段值。

例如,如果结构被(错误地)定义为:

struct = Struct("struct", 
    Flag("flag"), 
    UBInt8("optional_data"), 
    UBInt8("mandatory") 
) 

对于数据:

>>> struct.parse("010203".decode("hex")) 

结果应该是:

Container({'flag': True, 'mandatory': 3, 'optional_data': 2}) 

对于数据:

>>> struct.parse("000203".decode("hex")) 

期望的结果是:

Container({'flag': False, 'mandatory': 3, 'optional_data': None}) 

我尝试了以下方法:

struct = Struct("struct", 
    Flag("flag"), 
    IfThenElse("optional_data", lambda ctx: ctx.flag, 
        UBInt8("dummy"), 
        Padding(1) 
    ), 
    UBInt8("mandatory") 
) 

但是,Padding() 将原始数据放入字段中,如下所示:

>>> struct.parse("000203".decode("hex")) 
Container({'flag': False, 'mandatory': 3, 'optional_data': '\x02'}) 

谢谢

请您参考如下方法:

我不确定我是否正确理解你的问题。如果您的问题只是填充未被解析为 int,那么您不需要 IFThenElse。您可以检查代码中已解析的容器是否有标志,并选择忽略 optional_data 字段。

struct = Struct("struct", 
    Flag("flag"), 
    UBInt8("optional_data"), 
    UBInt8("mandatory") 
) 

如果您的问题是您希望仅在设置标志时使用名称 Optional Data 而在未设置标志时使用名称 dummy,那么您需要定义两个 Ifs

struct = Struct("struct", 
    Flag("flag"), 
    If("optional_data", lambda ctx: ctx.flag, 
        UBInt8("useful_byte"), 
    ), 
    If("dummy", lambda ctx: !ctx.flag, 
        UBInt8("ignore_byte"), 
    ), 
    UBInt8("mandatory") 
)