python中对象的散列和

2024-04-26 13:04:08 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的脚本中,我使用大型复杂对象(一个包含字符串、字典和自定义类型的类对象的多维列表)。我需要复制、pickle(缓存)和取消pickle,以及通过MPI接口在子进程之间发送。在某些情况下,我怀疑数据传输是没有错误的,也就是说,如果最后我有相同的对象。在

因此,我想计算它的散列和或其他类型的指纹。我知道,例如,hashlib库;但是,它在对象类型方面受到限制:

>>> import hashlib
>>> a = "123"
>>> hashlib.sha224(a.encode()).hexdigest()
'78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f'
>>> a = [1, 2, 3]
>>> hashlib.sha224(a).hexdigest()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object supporting the buffer API required

因此,问题是:有没有类似的函数可以处理任何类型的对象?在


Tags: 对象字符串脚本类型列表字典进程错误
2条回答

一种选择是递归地将结构的所有元素转换成散列对应的元素,即将列表转换为元组,将dict和对象转换为frozensets,然后简单地将hash()应用于整个元素。举例说明:

def to_hashable(s):
    if isinstance(s, dict):
        return frozenset((x, to_hashable(y)) for x, y in s.items())
    if isinstance(s, list):
        return tuple(to_hashable(x) for x in s)
    if isinstance(s, set):
        return frozenset(s)
    if isinstance(s, MyObject):
        d = {'__class__': s.__class__.__name__}
        d.update(s.__dict__)
        return to_hashable(d)
    return s

class MyObject:
    pass

class X(MyObject):
    def __init__(self, zzz):
        self.zzz = zzz

my_list = [
    1,
    {'a': [1,2,3], 'b': [4,5,6]},
    {1,2,3,4,5},
    X({1:2,3:4}),
    X({5:6,7:8})
]

print hash(to_hashable(my_list))

my_list2 = [
    1,
    {'b': [4,5,6], 'a': [1,2,3]},
    {5,4,3,2,1},
    X({3:4,1:2}),
    X({7:8,5:6})
]

print hash(to_hashable(my_list2)) # the same as above
pickle.dumps(...)

返回一个字符串,它是一个哈希对象。你可以这样做

^{pr2}$

相关问题 更多 >