'How to get data from memory if available in obj.__dict__?

I have a class something like :

def compute():
    # CPU savy task
    return some_value

def compute_other():
    # CPU savy task
    return some_value

class myclass:

    @property
    def value:
        # return if already computed => What can be done ?
        computed_value = compute()
        return computed_value

    @property
    def other:
        # return if already computed => What can be done ?
        computed_value = compute_other()
        return computed_value

ob = myclass()
print ob.value, ob.other
print ob.value, ob.other
print ob.value, ob.other

How can I intercept the method call to value and other and return the values if already available.

Can __getattribute__(self,name) be used to intercept any property and lookup if already available in self.__dict__ ?



Solution 1:[1]

Implement a memoization decorator and just apply it to your class:

@memoize
@property
    def value:
        # return if already computed => What can be done ?
        computed_value = compute()
        return computed_value

http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize

Solution 2:[2]

Using getattribute is over-complicating this problem. Simple getattr or even just structuring your property getter differently will work better and not leave you with the unintended consequences that result when using getattribute.

You should follow the form:

    @property
    def x:
        try:
            return self._x
        except AttributeError:
            self._x = foo()

alternatively:

    @property
    def x:
        if '_x' not in self.__dict__:
            self._x = foo()
        return self._x

finally, if you want to get fancier:

def __getattr__(self, name):
    getter = '_get_%s' % name
    try:
        value = getattr(self, getter)(self)
        setattr(self, name, value)
        return value
    except AttributeError:
        raise AttributeError('No getter defined for %s.' % name)

def _get_x(self):
    return foo()

This allows you to define any arbitrary new variable in the class by just writing another _get_var() method for it. Less boilerplate is usually good, unless you only will ever have one or two of these types of values attached to the class.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2