Hash a python new style class instance?

Given a custom instance of the python class in the new style, what is a good way to hash it and get a unique ID type value from it to be used for various purposes? Think of md5sum or sha1sum for this instance of the class.

The approach I'm currently using ignites the class and runs it through hexdigest, storing the resulting hash string in the class property (this property is never part of the pickle / spill procedures, fyi). Except when I came across a situation where a third-party module uses nested classes, and there is really no good way to uncover those who do not have hacks. I suppose I'm missing out on some kind of smart little Python trick to accomplish this.

Edit:

Sample code, because there is a requirement to get something relevant to the question. This class can be initialized, and the property self._uniq_idcan be configured correctly.

#!/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




This following class, however, cannot be initialized because it is Barnested in 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


The error I get is:

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) has both classes in it, so line number offset).


Etching requires a method __getstate__()that I discovered, so I also implemented __setstate__()for completeness. But given the pre-existing safety and brine warnings, there should be a better way to do this.


, , , Python . __main__.Bar, . , __main__.Foo.Bar , . SO- , " ", Python, , , - , , .

SO-, , , . , hashlib, , , bytearray ( , .NET), ( cPickle) bytearray.

0
2

, .

, id(foo) , , foo, repr(instance.__dict__), repr .

?

+2

hexdigests , , , . uuid, uuid.uuid4, uuid ...

0

All Articles