Python doesn't support complicated anonymous functions. What's a good alternative? For example:
class Calculation:
def __init__(self, func):
self.func = func
def __call__(self, data):
try:
# check if the value has already been calculated
# if it has, it would be cached under key = self.func
return data[self.func]
except KeyError:
pass # first-time call; calculate and cache the values
data[self.func] = self.func(data)
return data[self.func]
# with a simple function, which can be represented using lambda, this works great
f1 = Calculation(lambda data : data['a'] * data['b'])
# with a complicated function, I can do this:
def f2_aux:
# some complicated calculation, which isn't suitable for a lambda one-liner
f2 = Calculation(f2_aux)
Is this a reasonable design to begin with?
If so, is there a way to avoid the ugliness of f*_aux for each f* that I define in the module?
UPDATE:
Example of use:
d = {'a' : 3, 'b' : 6}
# computes 3 * 6
# stores 18 in d under a key <function <lambda> at ...>
# returns 18
f1(d)
# retrieves 18 from d[<function <lambda> at ...>]
# returns 18, without having to recalculate it
f1(d)
UPDATE:
Just for my understanding, I added a version that uses the inner function.
def memoize(func):
def new_func(data):
try:
# check if the value has already been calculated
# if it has, it would be cached under key = self.func
return data[func]
except KeyError:
pass # first-time call; calculate and cache the values
data[func] = func(data)
return data[func]
return new_func
@memoize
def f1(data):
return data['a'] * data['b']
f1 = lambda a: expressionis always exactly the same asdef f1(a): return expression. This is a good memoization decorator to study. BTW,@decorator def function: passis always exactly the same asdef function: pass; function = decorator(function)datais also the argument to your function...f(data)in the dictionary elementdata[f]. I know thatdatapassed to me won't ever use such a key - and conflict with another shouldn't happen either since another function's value would be cached under another key. It seems like it works (technically); is the problem just in the unnecessarily confusing code?data(say, a dictionary) is passed to the function:f1(data). The caller will keepdataalive as long as they need it, and if they ever callf1(data)again, the cache will kick in. (That's at least how I hoped it'd work.)datanow has a stale cached value!