Suppose I have some expensive function expensive_computation
which takes a long time to compute but it always returns the same value.
I want to avoid paying the cost of computing this function because it may never be called.
Here is my solution to this, is there a more obvious or clean way to do it? Or maybe even some function from the standard library?
def lazy(function):
internal_state = None
def lazy_evaluation():
nonlocal internal_state
if internal_state is None:
internal_state = function()
return internal_state
return lazy_evaluation
@lazy
def expensive_computation():
print("Working ...")
return "that was hard"
print(expensive_computation())
print(expensive_computation())
Which prints:
Working ...
that was hard
that was hard
1 Answer 1
if internal_state is None: internal_state = function()
What if function()
returns None
?
Or maybe even some function from the standard library?
-
\$\begingroup\$ So how do you change the code with regard to the first point if
None
is a valid return? \$\endgroup\$2019年05月03日 16:48:03 +00:00Commented May 3, 2019 at 16:48 -
\$\begingroup\$ My function never return
None
, but in the general case I guess that you would just have a boolean marker beside theinternal_state
, so you can tell if the function has been evaluated or not, but that's just a guess and probably not the best solution either. Concerning the cache solution I'll have a look at it. \$\endgroup\$cglacet– cglacet2019年05月03日 17:09:58 +00:00Commented May 3, 2019 at 17:09 -
\$\begingroup\$ @Peilonrayz, the obvious approach would be to use a separate Boolean variable. An alternative, which I consider hackier, would be to not have a separate variable for
internal_state
at all:result = function(); function = lambda () => result; return result
\$\endgroup\$Peter Taylor– Peter Taylor2019年05月03日 17:18:32 +00:00Commented May 3, 2019 at 17:18
lazy
up for review, and do you want any and all facets of your code reviewed? Please ensure your question is otherwise on-topic. \$\endgroup\$lazy
or the use of such a construct is what I'm looking for. I'm not sure what you mean by "real code", it's some working code, where I replaced every piece on which I don't want advice on by dummy code (I don't need advice on the content ofexpensive_computation
, that's why I don't provide its implementation). On the other hand, the implementation oflazy
is the exact one I intend to use. I added the output to make clear what behaviour I expect (because I noticed the term "lazy evaluation" is actually broader than this use case). \$\endgroup\$