Pythonic way to save method result as attribute

I have a python class with a property that performs an operation on large arrays. What is the best way to save the result of a method after its first calculation without repeated operation each time the resource is accessed?

For instance:

class MyClass:
    def __init__(self, x, y):
        """Input variables are two large data arrays"""
        self.x = x
        self.y = y

    @property
    def calculate(self):
        """Some computationally expensive operation"""
        try:
            # the result has been calculated already
            return self._result
        except AttributeError:
            # if not, calculate it
            self._result = self.x * self.y
            return self._result

Using:

>>> foo = MyClass(2,3)
>>> a = foo.calculate
>>> print(a)
6

As you can see, all I came up with is to have a “hidden” attribute in which the result is stored. Is there a better way to do this? Is it possible to use @propertyhere?

Thank.

+4
source share
4 answers

x y, . , .

class MyClass:
    def __init__(self, x, y):
        """Input variables are two large data arrays"""
        self.x = x
        self.y = y
        self._calculate = None
        self._x = None
        self._y = None

    @property
    def calculate(self):
        if not self._calculate or self._x != self.x or self._y != self.y:
            self._calculate = self.x * self.y
            self._x = self.x
            self._y = self.x

        return self._calculate


>>> a = MyClass(2,3)
>>> print(a.calculate)
6
>>> a.x = 553
>>> print(a.calculate)
1659
+3

, . .

. property ( ). - , __get__. , , , - (, ). .

class cache:
    def __init__(self, func):
        self.func = func

    def __get__(self, obj, type_):
        if obj is None:
            return self.func
        value = self.func(obj)
        setattr(obj, self.func.__name__, value)
        return value

class MyClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @cache
    def calculate(self):
        print("calculating")
        return self.x + self.y

o = MyClass(1, 2)
print("first", o.calculate) # prints "calcutating" then "first 3"
print("second", o.calculate) # just prints "second 3"
del o.calculate
print("third", o.calculate) # prints "calcutating" then "third 3"
+2

, . x y , _result , x y .

x y, , _result.

, x y lists ( , , arrays) MyClass. , , MyClass , x y . , .

+1

None, , None:

class MyClass:
    def __init__(self, x, y):
        """Input variables are two large data arrays"""
        self.x = x
        self.y = y
        self._result = None

    @property
    def calculate(self):
        """Some computationally expensive operation"""
        if self._result is not None:
            return self._result
        # if not, calculate it
        self._result = self.x * self.y
        return self._result
0

All Articles