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))
@TemporalWolfrepr
在这种情况下是不可靠的,因为它不会按固定顺序给你密钥,也不会给你对象可能包含的dict中的有序密钥。我一直在测试,它似乎不起作用。。。同样,似乎只考虑对象变量。。。如果继续向类中添加一个方法或修改一些常量,哈希值仍然是一样的……谢谢!它似乎起作用了!现在我在将其导入scons时遇到了一些问题,但那是另一回事;)