Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为任意对象创建哈希?_Python - Fatal编程技术网

Python 为任意对象创建哈希?

Python 为任意对象创建哈希?,python,Python,我一直在使用pickle.dumps为任意Python对象创建哈希,但是,我发现dict/set顺序没有规范化,因此结果不可靠 有这么多,但我似乎找不到一个使用相同等式基础的散列算法(\uuuu getstate\uuuu/\uu dict\uuuu结果)。我了解自己的滚动的基本要求,但显然我更喜欢使用经过测试的东西 有这样的图书馆吗?我想我实际上想要的是一个库,它可以确定地序列化对象(使用\uuuuu getstate\uuuuuuuuu和\uuuuu dict\uuuuuuu),这样我就可以

我一直在使用
pickle.dumps
为任意Python对象创建哈希,但是,我发现dict/set顺序没有规范化,因此结果不可靠

有这么多,但我似乎找不到一个使用相同等式基础的散列算法(
\uuuu getstate\uuuu
/
\uu dict\uuuu
结果)。我了解自己的滚动的基本要求,但显然我更喜欢使用经过测试的东西

有这样的图书馆吗?我想我实际上想要的是一个库,它可以确定地序列化对象(使用
\uuuuu getstate\uuuuuuuuu
\uuuuu dict\uuuuuuu
),这样我就可以散列输出了

编辑


为了澄清这一点,我正在寻找与Python(or)返回的值不同的东西。我想要的基本上是任意对象的校验和,这些对象可能是可散列的,也可能不是可散列的。此值应根据对象的状态而变化。(我用“state”指的是
\uuuu getstate\uuuu
返回的dict,或者,如果不存在,则指对象的
\uuu dict\uuuu

我假设一旦计算(并存储)了对象的散列值,就会将对象视为不可变的。否则,您应该非常小心您正在做的事情(例如,不应该使用它们的散列性质量来将它们存储在集合、dict等中)

也就是说,最优雅的方法是首先以可散列类型存储对象的
\uuu dict\uuu
中的所有成员。不要使用
list
s,而是使用元组(当然是可散列对象的元组)。不要使用
dict
s,而是使用任何问题的解决方案作为可哈希的dict类型(我个人使用@alex)。同样,键和值都必须是可散列的,才能工作

然后,您的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu散列
方法可以使用您正在使用的相同散列dict,如:

def _hashable_state(self):
    return MyHashableDict(self.__dict__)
def __hash__(self):
    return hash(self._hashable_state())
def __reduce__(self):
    return self._hashable_state()

我突然想到可以扩展Pickler并重写select函数来规范化必要的类型,所以这就是我正在做的。下面是它的样子:

from copy import copy
from pickle import Pickler, MARK, DICT
from types import DictionaryType


class CanonicalizingPickler(Pickler):
    dispatch = copy(Pickler.dispatch)

    def save_set(self, obj):
        rv = obj.__reduce_ex__(0)
        rv = (rv[0], (sorted(rv[1][0]),), rv[2])
        self.save_reduce(obj=obj, *rv)

    dispatch[set] = save_set

    def save_dict(self, obj):
        write = self.write
        write(MARK + DICT)

        self.memoize(obj)
        self._batch_setitems(sorted(obj.iteritems()))

    dispatch[DictionaryType] = save_dict

理解你想要散列的目的可能很有用。它本质上是为了记忆。我使用一组需要确定文件名的参数生成文件。但是,我对这个问题的一般解决方案感兴趣。请注意,您可以通过
\uuuu dict\uuu
的迭代顺序来区分两个“相等”的对象!是的,你说得对,我的对象是不可变的。然而,我正在寻找一种适用于任意(可pickle)对象的方法。也就是说,如果两个对象的状态字典中的所有项(
\uuuuu dict\uuuuu
\uuuu getstate\uuuuu()
结果)具有相同的哈希(递归情况),或者(对于没有
\uuu dict\uuuu
属性或
\uuu getstate\uuuuu
的原语或其他对象)相等,则这两个对象应该具有相同的哈希。