2016-11-16 102 views
0

我需要計算一個「哈希」,它允許我唯一標識一個對象,它是內容和父類。計算類和實例哈希

通過比較這些「散列」,我希望能夠判斷一個對象自上次掃描以來是否發生了變化。

我發現很多關於如何使一個哈希的對象實例,但沒有這麼多關於如何計算父類的哈希值。

重要的是要注意比較是在不同的執行過程中進行的。我這樣說是因爲我認爲比較對象的id(),因爲對於不同的執行,對象的id /地址可能會不同。

我認爲訴諸檢查,但我擔心它可能不是非常有效的,也是我不是很確定,將如何,如果該對象的父類是從另一個類繼承工作。

如果我有訪問到該實例和類的代碼存儲的實際內存的原始數據,我可以計算的散列。

任何想法?

+0

,如果你想知道如果自上次檢查改變你可以只生成你的對象的'__dict__'財產的哈希值。我認爲在這裏考慮其班級並不重要。 – lucasnadalutti

+0

我不確定內建的['hash()'](https://docs.python.org/2/library/functions.html#hash)沒有涵蓋什麼情況?你可以擴展嗎? – TemporalWolf

+0

@TemporalWolf如果你有'foo',一個'class Foo'的實例,做'foo.bar = 1','hash(foo)'會產生一個值,在你做完foo.bar後它將保持不變= 2'。 OP想要檢測這種變化。 – lucasnadalutti

回答

1

一般的想法是序列化對象,然後取一個散列。那麼,唯一的問題是找到一個好的圖書館。讓我們嘗試

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

看起來不錯?

蘿:https://github.com/uqfoundation

+0

謝謝!它似乎工作!現在我有一些麻煩導入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 
+0

我一直在測試,似乎沒有工作......再次只有對象變量似乎被考慮在內......如果繼續並向類中添加一個方法或修改某些常量,那麼哈希值仍然是相同的。 ... – viterbi