[英]Hash a python new-style class instance?
给定一个自定义的新型python类实例,对它进行哈希处理并从中获取唯一的类似于ID的值以用于各种用途的好方法是什么? 考虑给定类实例的md5sum或sha1sum。
我目前使用的方法是对类进行腌制,并通过hexdigest
运行,将生成的哈希字符串存储到class属性中(此属性永远不是pickle / unpickle过程的一部分,fyi)。 除了现在,我遇到了第三方模块使用嵌套类的情况,并且没有一种真正的好方法来腌制那些没有黑客的东西。 我认为我错过了一些聪明的Python小技巧来完成此任务。
编辑:
示例代码,因为这似乎是在此处获得问题解答的必要条件。 可以初始化下面的类,并且可以正确设置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,但是它带有严厉的警告,建议这种方法不建议使用,或者使用除酸洗以外的方法或将嵌套的类定义移至外部与内部。
但是,我认为,该SO答案的最初问题是对文件进行酸洗和酸洗。 我只需要腌制即可使用必需的hashlib
函数,这些函数似乎可以在hashlib
上运行(就像我在.NET中所习惯的那样),并且腌制(尤其是cPickle
)相对于编写自己的字节数组例程而言是快速且优化的。
这完全取决于ID应该具有的属性。
例如,只要foo
在内存中处于活动状态,就可以使用id(foo)
获得一个唯一的ID,或者如果所有字段都具有合理的repr
值,则可以使用repr(instance.__dict__)
。
您具体需要什么?
当您当前使用的是腌菜的十六进制时,您听起来好像id确实不需要与对象相关,而只是需要唯一。 为什么不简单地使用uuid模块,特别是uuid.uuid4来生成唯一的ID并将它们分配给对象中的uuid字段...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.