Pickle是否总是为某个输入值产生相同的输出?我想当酸洗词典具有相同的内容但插入/删除历史记录不同时,可能会出现问题。我的目标是使用Pickle和SHA1创建函数参数的“签名”,用于memoize实现。
答案 0 :(得分:8)
我认为当酸洗词典具有相同内容但插入/删除历史记录不同时,可能会出现问题。
右:
>>> pickle.dumps({1: 0, 9: 0}) == pickle.dumps({9: 0, 1: 0})
False
另请参阅:pickle.dumps not suitable for hashing
我的目标是使用Pickle和SHA1创建函数参数的“签名”,用于memoize实现。
这有很多基本问题。不可能想出一个正确映射相等性的对象到字符串转换 - 想一想对象标识的问题:
>>> a = object()
>>> b = object()
>>> a == b
False
>>> pickle.dumps(b) == pickle.dumps(a)
True
根据您的具体要求,您可以将对象层次结构转换为可以随后哈希的层次结构:
def hashablize(obj):
"""Convert a container hierarchy into one that can be hashed.
Don't use this with recursive structures!
Also, this won't be useful if you pass dictionaries with
keys that don't have a total order.
Actually, maybe you're best off not using this function at all."""
try:
hash(obj)
except TypeError:
if isinstance(obj, dict):
return tuple((k, hashablize(v)) for (k, v) in sorted(obj.iteritems()))
elif hasattr(obj, '__iter__'):
return tuple(hashablize(o) for o in obj)
else:
raise TypeError("Can't hashablize object of type %r" % type(obj))
else:
return obj
答案 1 :(得分:0)
你是什么意思相同的输出?通常情况下,您应该总是获得相同的输出(pickling - > unpickling),但我不认为序列化格式本身在各种条件下都保证是相同的。当然,它可能会在平台和所有这些之间发生变化。
在你的程序的一次运行中,使用酸洗进行记忆应该没问题 - 我已经多次使用这个方案而没有麻烦,但那是非常简单的问题。一个问题是,这并未涵盖所有有用的情况(函数浮现在脑海中:你不能腌制它们,所以如果你的函数采用可调用的参数,那将无效)。