繁体   English   中英

散列python新样式类实例?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM