计算类和实例哈希值

3
我需要计算一个“哈希值”,以便我能够唯一地识别一个对象,包括它的内容和父类。
通过比较这些“哈希值”,我希望能够确定对象自上次扫描以来是否发生了更改。
我已经找到了很多关于如何使对象可哈希的示例,但是关于如何计算父类的哈希值却不多。
需要注意的是,比较是在不同的执行期间进行的。我之所以这么说是因为我认为应该比较对象的id(),因为对象的id/地址可能在不同的执行期间有所不同。
我想过使用inspect,但我担心效率可能不是很高,而且如果对象的父类继承自另一个类,我也不太确定它会如何工作。
如果我可以访问实例和类代码存储的实际内存原始数据,那么我可以计算出其哈希值。
有什么想法吗?

如果你想知道对象自上次检查以来是否更改,那么你可以只生成该对象的__dict__属性的哈希值。我认为在这里考虑其类别并不重要。 - lucasnadalutti
如果你有一个名为fooFoo类实例,并执行foo.bar = 1,那么hash(foo)将生成一个值,在你执行foo.bar = 2之后仍然保持不变。OP想要检测这种更改。 - lucasnadalutti
@lucasnadalutti 可以使用 hash(repr(obj.__dict__)) - TemporalWolf
1
@TemporalWolf 在这种情况下,repr 不可靠,因为它不会按固定顺序给出键,也不会在对象可能包含有序键的字典中给出有序键。 - lucasnadalutti
我需要计算一个“哈希”,它可以让我唯一地识别一个对象 - 通常情况下,哈希并不能真正做到这一点。 - user2357112
显示剩余2条评论
2个回答

1
一般的想法是将对象序列化,然后进行哈希。现在的问题只是找一个好的库。让我们尝试使用 dill
>>>import dill
>>>class a():
    pass
>>>b = a()
>>>b.x = lambda x:1
>>> hash(dill.dumps(b))
2997524124252182619
>>> b.x = lambda x:2
>>> hash(dill.dumps(b))
5848593976013553511
>>> a.y = lambda x: len(x)
>>> hash(dill.dumps(b))
-906228230367168187
>>> b.z = lambda x:2
>>> hash(dill.dumps(b))
5114647630235753811
>>> 

你觉得怎么样?

dill: https://github.com/uqfoundation


谢谢!看起来它能工作了!现在我遇到了一些问题,无法将其导入到scons中,但这是另一回事 ;) - viterbi

0

为了检测一个对象是否发生了变化,你可以生成它的 JSON 表示的哈希值,并将其与相同方法生成的最新哈希值进行比较。

import json

instance.foo = 5
hash1 = hash(json.dumps(instance.__dict__, sort_keys=True))

instance.foo = 6
hash2 = hash(json.dumps(instance.__dict__, sort_keys=True))

hash1 == hash2
>> False

instance.foo = 5
hash3 = hash(json.dumps(instance.__dict__, sort_keys=True))

hash1 == hash3
>> True

或者,由于json.dumps给我们一个字符串,您可以直接比较它们而不是生成哈希值。

import json

instance.foo = 5
str1 = json.dumps(instance.__dict__, sort_keys=True)

instance.foo = 6
str2 = json.dumps(instance.__dict__, sort_keys=True)

str1 == str2
>> False

我一直在进行测试,但似乎不起作用...再次只有对象变量似乎被考虑在内...如果继续添加类的方法或修改某些常量,哈希值仍然相同... - viterbi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接