1

我有一个包含一些成员的类,以及一些访问这些成员的方法。我想缓存这些方法,但是每次其中一个成员更改时,他们都不应该访问缓存,而是再次运行。它类似于每个成员的 is_changed 标志。有正确的方法吗?

4

1 回答 1

1

You can try something like the following to generate a unique hash for each object:

try:
    import numpy as np
    has_np=True
except ImportError:
    has_np=False

def hash_any(value, hv=None):
    hv = hv or 0
    if value is None or isinstance(value, (str, unicode, int, long, float, bool)):
        hv = hash(value) ^ hv
    elif  has_np and np.isscalar(value):
        hf = hash(value) ^ hv
    elif isinstance(value, (list, tuple, set)):
        for x in value:
            hv = hash_any(x, hv)
    elif isinstance(value, dict):
        for k,v in value.iteritems():
            hv = hash_any(k, hv)
            hv = hash_any(v, hv)
    elif isinstance(value, slice):
        # Hash a tuple of the slice components
        hv = hash((value.start, value.stop, value.step)) ^ hv
    elif isinstance(value, object):
        hv = hash_any(value.__dict__, hv)

    return hv

Then, given an object like:

class MyObj(object):

    def __init__(self):
        self.memb1 = 'blar'
        self.memb2 = 2124
        self.memb3 = {'a':2,'b':'some'}

You can compare the hash at different times to determine if change to any member has occurred:

In [1]: cls = MyObj()

In [2]: h1 = hash_any(cls)

In [3]: h1
Out[3]: -4385883409912780426

In [4]: cls.memb1 = 'dog'

In [4]: h2 = hash_any(cls)

In [5]: h2
Out[5]: 3758072334382950160

In [6]: cls.memb3['b'] = 'top'

In [7]: h3 = hash_any(cls)

In [8]: h3
Out[8]: 4138015896510837430

If you only wanted to hash on some members of the object, you could run the hash on each individually and then combine them with the ^ operator. This could even be done as a method of the object itself.

class MyObj(object):

    def __init__(self):
        self.memb1 = 'blar'
        self.memb2 = 2124
        self.memb3 = {'a':2,'b':'some'}

    def myhash(self):
        h = 0
        tohash = ['memb1', 'memb2']
        for m in tohash:
            h = h ^ hash_any(getattr(self, m))

        return h

And then compare myobj.myhash over time.

于 2013-06-27T16:15:13.137 回答