我有一个简单的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.'
这只是对象属性排序的差异还是更多呢?
答案 0 :(得分:2)
在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}