Python 计算类和实例哈希

Python 计算类和实例哈希,python,object,hash,Python,Object,Hash,我需要计算一个“散列”,它允许我唯一地标识一个对象,包括它的内容和父类 通过比较这些“散列”,我想知道一个对象自上次扫描以来是否发生了变化 我已经找到了很多关于如何使对象可散列的例子,但是没有太多关于如何计算父类的散列的例子 需要注意的是,在不同的执行过程中进行了比较。我这样说是因为我认为比较对象的id(),因为对象的id/地址对于不同的执行可能是不同的 我曾想过使用inspect,但我担心它可能不是很有效,而且我也不确定如果对象的父类继承自另一个类,那么它将如何工作 如果我能够访问存储实例和类

我需要计算一个“散列”,它允许我唯一地标识一个对象,包括它的内容和父类

通过比较这些“散列”,我想知道一个对象自上次扫描以来是否发生了变化

我已经找到了很多关于如何使对象可散列的例子,但是没有太多关于如何计算父类的散列的例子

需要注意的是,在不同的执行过程中进行了比较。我这样说是因为我认为比较对象的
id()
,因为对象的id/地址对于不同的执行可能是不同的

我曾想过使用inspect,但我担心它可能不是很有效,而且我也不确定如果对象的父类继承自另一个类,那么它将如何工作

如果我能够访问存储实例和类代码的实际内存原始数据,我就可以计算其哈希


有什么想法吗?

要检测对象是否已更改,您可以生成其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

一般的想法是序列化对象,然后进行散列。那么,唯一的问题就是找到一个好的图书馆。让我们试试迪尔吧:

>>>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:

如果您想知道对象的
\uuu dict\uuu
属性自上次检查以来是否发生了更改,您可以只生成对象的
\uuu dict\uuuu>属性的散列。我不认为考虑它的类在这里是重要的。我不确定什么情况不包括在内置的?你能扩展一下吗?@TemporalWolf如果你有
foo
,一个
类foo
的实例,并且执行
foo.bar=1
hash(foo)
将生成一个值,在执行
foo.bar=2
之后,该值将保持不变。OP想要检测这种变化。@lucasnadalutti可以使用
hash(repr(obj.\uu dict\uuuuu))
@TemporalWolf
repr
在这种情况下是不可靠的,因为它不会按固定顺序给你密钥,也不会给你对象可能包含的dict中的有序密钥。我一直在测试,它似乎不起作用。。。同样,似乎只考虑对象变量。。。如果继续向类中添加一个方法或修改一些常量,哈希值仍然是一样的……谢谢!它似乎起作用了!现在我在将其导入scons时遇到了一些问题,但那是另一回事;)