字典表现异常,如何打包成二进制

0 投票
2 回答
723 浏览
提问于 2025-04-16 06:36

我有一段代码:

    from struct import pack
    self.data = {'SYNC' : 0x16, 'SOH' : 0x01,
                 'FnCode' : 0x55, 'pacingState' : 0,
                 'pacingMode' : 6, 'hysteresis' : 0,
                 'hysteresisInterval' : 300, 'lowrateInterval' : 1000,
                 'vPaceAmp' : 3500, 'vPaceWidth' : 4,
                 'VRP' : 320, 'spare' : '\x00\x00\x00\x00\x00'}
    print(self.data.keys())
    print(self.data.values())

    pack('BBBBBBHHHHH5s', self.data.values())

我得到了这个输出:

dict_keys(['pacingState', 'SYNC', 'hysteresis', 'FnCode', 'spare', 'lowrateInterval', 'vPaceWidth', 'VRP', 'SOH', 'pacingMode', 'hysteresisInterval', 'vPaceAmp'])

dict_values([0, 22, 0, 85, '\x00\x00\x00\x00\x00', 1000, 4, 320, 1, 6, 300, 3500])

为什么这些值的顺序和我在字典里写的顺序不一样?我该怎么才能让它们按我写的顺序显示呢?

还有,当我尝试使用pack函数时,它告诉我需要12个参数,而data.values有12个值,所以我不明白为什么会出错。

我试着创建一个字典,里面引用了一个包含这些值的数组(这样我就可以把数组传进去,因为它的顺序是对的),但改变字典里的值并没有影响到它所引用的实际值数组,所以这个主意也不行了……

提前谢谢你。

2 个回答

3

字典(Dictionaries)并不会记住你添加键的顺序,因为它们是哈希表,根本不记录键的插入顺序。如果你需要一个有顺序的字典,Python 2.7 和 3.1 版本提供了一个叫做 collections.OrderedDict 的工具。如果你用的是更早的 Python 版本,可以看看这个 ActiveState 的教程

至于你的 pack 为什么会出错——其实你并没有传递 12 个参数(只要你的格式字符串是这样),你只是传递了一个参数,这个参数是一个列表。

补充 delnan 的帖子告诉你如何拆解你的值。

3
  1. 字典是无序的。也就是说,它们不会突然按某种方式重新排序,但它们也不会保持你插入的顺序,或者说是有序的。你可以把它们当作顺序是随机的来处理。如果你需要保持顺序,可以使用 collections.OrderedDict(如果你用的是旧版本的Python,标准库里没有这个,可以在网上找到很多实现)。或者,如果你只需要值而不需要键(也就是说,键只是用来做说明),你可以用一个 list 来存这些值,这样是有顺序的。
  2. 关于需要12个参数的打包问题:你其实只给了它一个参数,data.values()。虽然这个参数里面有12个对象,但它仍然算作一个参数。你可以使用 pack(... ,*data.values()) 来把这12个对象拆开,变成12个单独的参数。

撰写回答