在Python中清晰地记住整个块/匿名函数

时间:2019-04-08 14:45:46

标签: python anonymous-function memoization

用Python记住整个计算块(多行lambda,如果可以创建的话)的最干净方法是什么?

在备忘录中,我打算给出一个通用的名称:“如果已经计算出结果,则从某个地方加载它。否则将其计算并保存到某个地方。”

我当前的解决方案(用于将任意计算结果缓存到磁盘的内容写成):

  1. 有一个装饰器进行缓存(它将文件名保存/加载到的位置作为参数):
from functools import wraps

def disk_cache(filename):
    def decorator(compute_result_func):
        @wraps(compute_result_func) # don't shadow function's docstring
        def wrapped(*args, **kwargs):
            if not os.path.exists(filename):
                # compute and save
                print "compute"
                result = compute_result_func()
                print "save"
                pickle.dump(result, open(filename, 'wb'))
            else:
                # load
                print "load"
                result = pickle.load(open(filename, 'rb'))
            return result
        return wrapped
    return decorator
  1. 每当我想记住一个计算块时,我都会将其包装到一个具有通用名称(如果可以的话,我将使用多行lambda)的函数,该函数不带任何内容(只捕获位于较大的范围)并返回单个结果。我用装饰器装饰了此函数,然后立即调用该函数。
@disk_cache(filename='/path/to/dump.pkl')
def multi_line_lambda():
    # do some stuff
    x = 2 ** 2
    y = 7
    return x + y
multi_line_lambda()

是否可以使用语法上更简洁的模式?像

with cache(filename):
    do x
    do y
    return result # which is actually just loaded if already existing

1 个答案:

答案 0 :(得分:0)

我过去曾探讨过这个确切的问题(无耻的插件:这里是my result),发现最好使用现有的方法。但是,如果您愿意滥用Python语法,请按以下步骤操作:

def disk_cache(filename):
    def decorator(compute_result_func):
        if not os.path.exists(filename):
            result = compute_result_func()
            pickle.dump(result, open(filename, 'wb'))
        else:
            result = pickle.load(open(filename, 'rb'))
        return result
    return decorator

现在,

@disk_cache(filename='/path/to/dump.pkl')
def calculated_stuff():
    # do some stuff
    x = 2 ** 2
    y = 7
    return x + y
# at this point, calculated_stuff() already contains the result (11)

请记住,这是一种肮脏的做法。不要用别人可以阅读的代码来做