給定一個自定義的新樣式的python類實例,散列它並從中獲取唯一的類ID值以用於各種用途的好方法是什麼?考慮給定類實例的md5sum或sha1sum。散列一個python新樣式類實例?
我目前使用的方法是把pickles類運行並通過hexdigest
運行,將結果散列字符串存儲到類屬性中(該屬性永遠不是pickle/unpickle過程的一部分,fyi)。除了現在我已經遇到了第三方模塊使用嵌套類的情況,並且沒有真正好的方法來挑選那些沒有一些黑客的東西。我覺得我錯過了一些聰明的小竅門,在某處完成這個任務。
編輯:
示例代碼,因爲它似乎是一個需要在這裏工作再上一個問題的任何牽引力。下面的類可以初始化,並且self._uniq_id
屬性可以正確設置。
#!/usr/bin/env python
import hashlib
# cPickle or pickle.
try:
import cPickle as pickle
except:
import pickle
# END try
# Single class, pickles fine.
class FooBar(object):
__slots__ = ("_foo", "_bar", "_uniq_id")
def __init__(self, eth=None, ts=None, pkt=None):
self._foo = "bar"
self._bar = "bar"
self._uniq_id = hashlib.sha1(pickle.dumps(self, -1)).hexdigest()[0:16]
def __getstate__(self):
return {'foo':self._foo, 'bar':self._bar}
def __setstate__(self, state):
self._foo = state['foo']
self._bar = state['bar']
self._uniq_id = hashlib.sha1(pickle.dumps(self, -1)).hexdigest()[0:16]
def _get_foo(self): return self._foo
def _get_bar(self): return self._bar
def _get_uniq_id(self): return self._uniq_id
foo = property(_get_foo)
bar = property(_get_bar)
uniq_id = property(_get_uniq_id)
# End
這下一個類,但是,不能因爲Bar
初始化被嵌套在Foo
:
#!/usr/bin/env python
import hashlib
# cPickle or pickle.
try:
import cPickle as pickle
except:
import pickle
# END try
# Nested class, can't pickle for hexdigest.
class Foo(object):
__slots__ = ("_foo", "_bar", "_uniq_id")
class Bar(object):
pass
def __init__(self, eth=None, ts=None, pkt=None):
self._foo = "bar"
self._bar = self.Bar()
self._uniq_id = hashlib.sha1(pickle.dumps(self, -1)).hexdigest()[0:16]
def __getstate__(self):
return {'foo':self._foo, 'bar':self._bar}
def __setstate__(self, state):
self._foo = state['foo']
self._bar = state['bar']
self._uniq_id = hashlib.sha1(pickle.dumps(self, -1)).hexdigest()[0:16]
def _get_foo(self): return self._foo
def _get_bar(self): return self._bar
def _get_uniq_id(self): return self._uniq_id
foo = property(_get_foo)
bar = property(_get_bar)
uniq_id = property(_get_uniq_id)
# End
我收到的錯誤是:
Traceback (most recent call last):
File "./nest_test.py", line 70, in <module>
foobar2 = Foo()
File "./nest_test.py", line 49, in __init__
self._uniq_id = hashlib.sha1(pickle.dumps(self, -1)).hexdigest()[0:16]
cPickle.PicklingError: Can't pickle <class '__main__.Bar'>: attribute lookup __main__.Bar failed
( nest_test.py
)有兩個類,因此行號偏移量)。
酸洗需要我發現的__getstate__()
方法,所以爲了完整性我也實施了__setstate__()
。但考慮到已經存在的關於安全和醃製的警告,有一個更好的方法來做到這一點。
根據我到目前爲止閱讀的內容,錯誤源於Python無法解析嵌套類。它試圖查找不存在的屬性__main__.Bar
。它確實需要能夠找到__main__.Foo.Bar
,但沒有真正的好方法來做到這一點。我在這裏遇到了另一個SO回答,它提供了一個「詭計」來哄騙Python,但它帶着一個嚴厲的警告,認爲這種方法是不可取的,要麼使用酸洗之外的其他方法,要麼將嵌套類定義移動到外部與內部相比。
但是,我相信這個答案的原始問題是用於酸洗和取出文件。我只需要醃菜以便使用必要的hashlib
函數,這些函數似乎在字節數組上運行(很像我在.NET中使用的),而酸洗(特別是cPickle
)與編寫我自己的字節陣列例程相比,速度更快且優化。
仍在學習Python,所以我不熟悉所有類的花哨。什麼,確切地說,是'id()'? – Kumba 2012-02-18 08:03:35
@Kumba在CPython中,id()讓你獲得對象的內存地址。 – 2012-02-18 08:59:27
@Kumba:repr建議是否不符合您的需求?這似乎是顯而易見的方式來做到這一點。 – Marcin 2012-02-18 11:10:17