酸洗过程是确定性的吗?

发布于 2024-07-24 08:31:00 字数 120 浏览 14 评论 0原文

对于特定的输入值,Pickle 是否总是产生相同的输出? 我想当腌制具有相同内容但不同插入/删除历史记录的字典时可能会出现问题。 我的目标是使用 Pickle 和 SHA1 创建函数参数的“签名”,以实现 memoize。

Does Pickle always produce the same output for a certain input value? I suppose there could be a gotcha when pickling dictionaries that have the same contents but different insert/delete histories. My goal is to create a "signature" of function arguments, using Pickle and SHA1, for a memoize implementation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅哥哥的热头脑 2024-07-31 08:31:00

我想当腌制具有相同内容但不同插入/删除历史记录的字典时可能会出现问题。

右:

>>> pickle.dumps({1: 0, 9: 0}) == pickle.dumps({9: 0, 1: 0})
False

另请参阅:pickle.dumps 不适合散列

我的目标是使用 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

I suppose there could be a gotcha when pickling dictionaries that have the same contents but different insert/delete histories.

Right:

>>> pickle.dumps({1: 0, 9: 0}) == pickle.dumps({9: 0, 1: 0})
False

See also: pickle.dumps not suitable for hashing

My goal is to create a "signature" of function arguments, using Pickle and SHA1, for a memoize implementation.

There's a number of fundamental problems with this. It's impossible to come up with an object-to-string transformation that maps equality correctly—think of the problem of object identity:

>>> a = object()
>>> b = object()
>>> a == b
False
>>> pickle.dumps(b) == pickle.dumps(a)
True

Depending on your exact requirements, you may be able to transform object hierarchies into ones that you could then hash:

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
夜清冷一曲。 2024-07-31 08:31:00

相同的输出是什么意思? 通常,您应该始终获得相同的往返输出(pickling -> unpickling),但我不认为序列化格式本身在每种情况下都保证相同。 当然,它可能会在平台之间发生变化等等。

在程序的一次运行中,使用 pickling 进行记忆应该没问题 - 我已经多次使用此方案,没有遇到任何问题,但那是针对非常简单的问题。 一个问题是,这并没有涵盖所有有用的情况(我想到的是函数:你无法对它们进行腌制,所以如果你的函数采用可调用参数,那将不起作用)。

What do you mean by same output ? You should normally always get the same output for a roundtrip (pickling -> unpickling), but I don't think the serialized format itself is guaranteed to be the same in every condition. Certainly, it may change between platforms and all that.

Within one run of your program, using pickling for memoization should be fine - I have used this scheme several times without trouble, but that was for quite simple problems. One problem is that this does not cover every useful case (function come to mind: you cannot pickle them, so if your function takes a callable argument, that won't work).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文