如果输入参数的散列已知,如何编写python函数包装器来加载结果?

如果输入参数的散列已知,如何编写python函数包装器来加载结果?,python,machine-learning,Python,Machine Learning,我的机器学习环境中的许多功能都是确定性的。也就是说,对于相同的输入,它们总是有完全相同的输出 因为我经常使用相同的参数调用这些函数,所以我想自动检测计算是否在之前完成。如果是,则从pickle文件重新加载,否则使用参数散列计算并存储到pickle文件 我如何实现这一点?使用包装器类?装饰器?您可以使用装饰器更新列表,其中包含调用的每个函数的名称,以便以后在包装器中使用: import pickle called_functs = [] def called(f): def call_wrap

我的机器学习环境中的许多功能都是确定性的。也就是说,对于相同的输入,它们总是有完全相同的输出

因为我经常使用相同的参数调用这些函数,所以我想自动检测计算是否在之前完成。如果是,则从pickle文件重新加载,否则使用参数散列计算并存储到pickle文件


我如何实现这一点?使用包装器类?装饰器?

您可以使用装饰器更新列表,其中包含调用的每个函数的名称,以便以后在包装器中使用:

import pickle
called_functs = []
def called(f):
  def call_wrapper(*args, **kwargs):
     if f.__name__ in called_functs:
        data = pickle.load(open('filename.txt'))
        #do something with data
     else:
        global called_functs
        called_functs.append(f.__name__)
        pickle.dump([args, kwargs, f(*args, **kwargs)], open('filename.txt', 'w'))
   return call_wrapper

@called
def backpropagate(*args, **kwargs): #example from a neural net
   pass
   #do something

我投了否决票,因为1/在不必要时使用全局,2/在不必要时使用
global
语句,3/使用相对路径访问文件,4/未关闭的文件,5/事实上装饰程序实际上从不调用装饰函数,当然,因为对
调用的
列表和修饰函数使用相同的名称只会中断装饰函数内部对
调用的
的所有使用。@Brunodesshuilliers感谢您指出名称冲突,它已修复。然而,你能推荐一个更好的替代使用globals的方法吗?关于这些文件,这些只是根据OP在其帖子中提到的内容进行演示。此外,我还添加了对包装函数的a调用,但是,我不确定OP是否只想截获传递的函数参数并调用函数,还是只执行前者。“你能推荐一个更好的替代全局函数的方法吗?”当然可以。哦,顺便说一句:你的(现在改名的)
名为_functs
的列表只在进程期间有效,对文件进行记忆的目的是获取共享和/或持久缓存,而你的解决方案不提供这些缓存。“关于文件,这些只是为了演示。”:很多新手或非程序员可能不知道为什么不关闭文件是不好的。当我们回答这个问题时,我们的职责是在这个过程中尝试并教给读者良好的实践。因此,请不要“例如”发布错误代码,或至少提及错误代码的位置和方式,以及在真实代码中应处理的内容。文件访问也不是免费的,您是舒尔公司的吗?您想使用文件作为缓存吗?根据执行上下文,可能有更好的选择(进程内存、内存外部缓存、持久外部缓存等)。除此之外,这种模式(在它的通用形式中)被命名为“memorization”,您会发现大多数示例将使用“进程内存”缓存,但可以很容易地适应某些外部缓存。扰流板,我是这个库的创建者。@SvetlinMladenov您的库似乎很有趣,但在分布式环境中无法工作,分布式环境正成为计算繁重任务的标准。我认为您应该扩展它,以允许使用memcache或redis作为共享(在redis的情况下最终是持久的)缓存存储,或者至少提供一种方法来实现自己的缓存支持并使其可配置。