1

My problem simplified:

Let's assume that method_1 is a computationally heavy function. There's a possibility that it won't be necessary to call it at all when working with the instance of the class (so I don't want to put it in the inside the init-function). Then there is the other possibility that method_2 will be called multiple times and with my current solution in that case every time also the method_1 is called.

What would be easiest and most pythonic solution?

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

   def method_1(self)
      # method that returns list which values vary depending on x and y
      return some_list


   def method_2(self, a)
      # method that modifies and returns specific list element from some_list according to a
      return do_modifications(self.method_1(), a)


   def method_3(self, arg1, ...)
      #some method
   ...
4
  • 1
    Not sure if this is the most pythonic but a possible solution is to save the list as a member of the class and then before method_2 calls method one it could check if the list already has a value, If its empty call method one if not use the saved list Commented Mar 19, 2020 at 17:16
  • 2
    Use memoization. Commented Mar 19, 2020 at 17:17
  • As a side note, there is really no reason to be using double underscores in your attribute names here. See this question for more information on why this is not a good practice in Python. Commented Mar 19, 2020 at 17:22
  • Just like @TomKarzes mentioned the caching data that you will reuse would be the most pythoninc way of doing things. Commented Mar 19, 2020 at 17:37

2 Answers 2

3

If you're using Python 3.8, you can use functools.cache_property:

@functools.cached_property(func)

Transform a method of a class into a property whose value is computed once and then cached as a normal attribute for the life of the instance. Similar to property(), with the addition of caching. Useful for expensive computed properties of instances that are otherwise effectively immutable.

Sign up to request clarification or add additional context in comments.

Comments

1

Make method1's return value a property. (This is basically what functools.cached_property does; use that if possible.)

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

   def _method1(self):
       return some_list

   # Call _method1 on demand the first time you need
   # the result of self._method1(), and save the result for future
   # accesses
   @property
   def m1_data(self)
      if self._m1_data is None:
          self._m1_data = self._method1()
      return self._m1_data


   def method_2(self, a)
      return do_modifications(self.m1_data, a)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.