Ryuku Hideki
Ryuku Hideki

Reputation: 29

How can I reuse return values in a Python class without rerunning the function every time?

I'm having a problem when reusing a function inside a class. I would like to get the return value of a function without rerunning it every time I use it. What is the best way of doing this inside a class?

Thank you!

class Test():

    def __init__ (self):
        # self.my_list = my_list()

        pass


    @staticmethod
    def my_list():
        set_list = [1, 2, 3, 4, 5, 6] 
        print ('you are not refrencing')

        return set_list

    @staticmethod
    def func_test():
        func_list = Test.my_list()
        return func_list


    @staticmethod
    def func_test2():
        func_list = Test.my_list()
        return func_list

    @staticmethod
    def print_func():
        print Test.my_list()
        print Test.func_test()
        print Test.func_test2()

        return

Test.print_func()

here is my current result:

you are not referencing 
[1, 2, 3, 4, 5, 6]
you are not referencing
[1, 2, 3, 4, 5, 6]
you are not referencing
[1, 2, 3, 4, 5, 6]

I would get this result instead

you are not referencing 
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]

Upvotes: 2

Views: 1310

Answers (2)

Jainil Patel
Jainil Patel

Reputation: 1324

import functools

class Test():

    def __init__ (self):
        # self.my_list = my_list()

        pass


    @staticmethod
    @functools.lru_cache(maxsize=128, typed=False)
    def my_list():
        set_list = [1, 2, 3, 4, 5, 6] 
        print ('you are not refrencing')

        return set_list

    @staticmethod
    def func_test():
        func_list = Test.my_list()
        return func_list


    @staticmethod
    def func_test2():
        func_list = Test.my_list()
        return func_list

    @staticmethod
    def print_func():
        print (Test.my_list())
        print (Test.func_test())
        print (Test.func_test2())

        return

Test.print_func()

you can try this code if you are in python 2.7

from repoze.lru import lru_cache

@lru_cache(maxsize=500)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

Upvotes: 0

gilch
gilch

Reputation: 11651

If your functions are pure (no side effects/same inputs always produce the same outputs), you can use memoization with @functools.lru_cache, which caches the output for a given set of inputs. (This is backed by a dict, so the arguments must be hashable.)

If the function is not pure (like your example with the print() call inside) then adding this decorator will change the behavior: the side effects will be skipped on the following calls. Also be very careful when you return a mutable value (like a list) because the same cached object will be returned, even if anything has mutated it, which might not be what you expect.

Upvotes: 3

Related Questions