【问题标题】:pickle.dumps returns a different output on each callpickle.dumps 在每次调用时返回不同的输出
【发布时间】:2014-10-06 14:49:40
【问题描述】:

我有一个简单的 python 脚本,可以腌制一个对象并打印它。

import pickle

o = {'first':1,'second':2,'third':3,'ls':[1,2,3]}
d = pickle.dumps(o) 
print(d)

以下是我多次执行同一个脚本时得到的输出:

  • b'\x80\x03}q\x00(X\x05\x00\x00\x00firstq\x01K\x01X\x05\x00\x00\x00thirdq\x02K\x03X\x06\x00\x00\x00secondq\x03K\x02X\x02\x00\x00\x00lsq\x04]q\x05(K\x01K\x02K\x03eu.'

  • b'\x80\x03}q\x00(X\x05\x00\x00\x00thirdq\x01K\x03X\x02\x00\x00\x00lsq\x02]q\x03(K\x01K\x02K\x03eX\x05\x00\x00\x00firstq\x04K\x01X\x06\x00\x00\x00secondq\x05K\x02u.'

  • b'\x80\x03}q\x00(X\x05\x00\x00\x00firstq\x01K\x01X\x06\x00\x00\x00secondq\x02K\x02X\x02\x00\x00\x00lsq\x03]q\x04(K\x01K\x02K\x03eX\x05\x00\x00\x00thirdq\x05K\x03u.'

  • b'\x80\x03}q\x00(X\x05\x00\x00\x00thirdq\x01K\x03X\x05\x00\x00\x00firstq\x02K\x01X\x02\x00\x00\x00lsq\x03]q\x04(K\x01K\x02K\x03eX\x06\x00\x00\x00secondq\x05K\x02u.'

仅仅是对象属性的排序不同还是有更多?

【问题讨论】:

    标签: python python-3.x dictionary pickle


    【解决方案1】:

    在 Python 3 中,字典顺序取决于哈希随机化。每次启动解释器时,都会使用不同的随机哈希种子。如果您要打印字典,您也会看到不同的顺序:

    $ bin/python -c "o = {'first':1,'second':2,'third':3,'ls':[1,2,3]}; print(o)"
    {'first': 1, 'ls': [1, 2, 3], 'second': 2, 'third': 3}
    $ bin/python -c "o = {'first':1,'second':2,'third':3,'ls':[1,2,3]}; print(o)"
    {'ls': [1, 2, 3], 'third': 3, 'first': 1, 'second': 2}
    $ bin/python -c "o = {'first':1,'second':2,'third':3,'ls':[1,2,3]}; print(o)"
    {'second': 2, 'ls': [1, 2, 3], 'third': 3, 'first': 1}
    

    Python 使用随机种子来防止针对将传入用户数据解析为字典的程序(例如 Web 服务器)的某些类型的拒绝服务攻击;否则,这种攻击可以预测两个字符串何时会导致字典中的哈希冲突,并提供除了创建冲突之外什么都不做的 Python 值,从而减慢 Python 程序的爬行速度。

    您可以使用PYTHONHASHSEED environment variable 将种子设置为固定值,或者您可以完全禁用哈希随机化:

    整数必须是 [0,4294967295] 范围内的十进制数。指定值 0 将禁用哈希随机化。

    $ PYTHONHASHSEED=0 bin/python -c "o = {'first':1,'second':2,'third':3,'ls':[1,2,3]}; print(o)"
    {'third': 3, 'ls': [1, 2, 3], 'first': 1, 'second': 2}
    $ PYTHONHASHSEED=0 bin/python -c "o = {'first':1,'second':2,'third':3,'ls':[1,2,3]}; print(o)"
    {'third': 3, 'ls': [1, 2, 3], 'first': 1, 'second': 2}
    

    另见:Why is the order in dictionaries and sets arbitrary?

    【讨论】:

    • 有趣的是,我需要再等 7 分钟才能接受这篇文章,即使我在不​​到一分钟的时间内就得到了我想要的答案。
    猜你喜欢
    • 2020-11-26
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    相关资源
    最近更新 更多