检查点

ediblepickle的Python项目详细描述


https://travis-ci.org/mpavan/ediblepickle.png?branch=master

ediblepickle是一个apache v 2.0许可的checkpointing实用程序。 最简单的用例是检查一个昂贵的计算,该计算不需要每次程序被 执行,如:

importstringimporttimefromediblepickleimportcheckpoint# A checkpointed expensive function@checkpoint(key=string.Template('m{0}_n{1}_${iterations}_$stride.csv'),work_dir='/tmp/intermediate_results',refresh=True)defexpensive_computation(m,n,iterations=4,stride=1):foriinrange(iterations):time.sleep(1)returnrange(m,n,stride)# First call, evaluates the function and saves the resultsbegin=time.time()expensive_computation(-100,200,iterations=4,stride=2)time_taken=time.time()-beginprinttime_taken# Second call, since the checkpoint exists, the result is loaded from that file and returned.begin=time.time()expensive_computation(-100,200,iterations=4,stride=2)time_taken=time.time()-beginprinttime_taken

功能

  • 通用装饰器API
  • 检查点昂贵的函数,以避免在开发时重新计算
  • 可配置的计算缓存存储格式(即使用人性化的密钥和数据,而不是pickle二进制数据)
  • 指定“刷新”以刷新缓存并重新计算
  • 指定自己的序列化/反序列化(保存/加载)函数
  • python日志,只需定义自己的日志来激活它

安装

要安装EdiblePickle,只需:

$ pip install ediblepickle

或:

$ easy_install ediblepickle

示例

另一个不错的特性是能够定义自己的序列化器和反序列化器。 使它们是人类可读的。例如,可以使用numpy/scipy实用程序 保存要调试的矩阵或csv文件:

importstringimporttimefromediblepickleimportcheckpointfromsimilarity.utilsimportdict_configdefmy_pickler(integers,f):printintegersforiinintegers:f.write(str(i))f.write('\n')defmy_unpickler(f):returnf.read().split('\n')@checkpoint(key=string.Template('m{0}_n{1}_${iterations}_$stride.csv'),pickler=my_pickler,unpickler=my_unpickler,refresh=False)defexpensive_computation(m,n,iterations=4,stride=1):foriinrange(iterations):time.sleep(1)returnrange(m,n,stride)begin=time.time()printexpensive_computation(-100,200,iterations=4,stride=2)time_taken=time.time()-beginprinttime_takenbegin=time.time()printexpensive_computation(-100,200,iterations=4,stride=2)time_taken=time.time()-beginprinttime_taken

关键规格

缓存函数输出的键可以用4种不同的方式指定。

  1. a python字符串:使用python str对象指定的键被视为原样。函数decorated的输出被保存 在文件名为的文件中。

  2. string.template对象:发送到函数的参数和Kwargs用于使用string.template对象生成名称。 例如,对于函数f(a,b,arg3=10,arg4=9),(a,b)是参数,(arg3,arg4)是关键字参数。 非关键字参数使用其位置表示。即{0}转换为参数a的值。 关键字参数使用标准模板表示法表示。例如,${arg3}将取arg3的值。

    例如:

@checkpoint(key=string.Template('{0}_bvalue_{1}_${arg3}_${arg4}_output.txt'))deff(a,b,arg3=8,arg4='subtract'):# do something with the argsresult=(a-b)/arg3returnresult
  1. lambda函数:lambda args,kwargs:…形式的任何lambda函数都适合用作密钥生成器。非关键字参数 以元组形式代替“args”发送,关键字参数以字典形式代替“kwargs”发送。你可以用 它们编写任何复杂的函数来生成并返回一个密钥名。

    例如,下面两个选项中的任何一个,在调用时:f(3,4,arg3=19,arg4='add'),生成:“3_bvalue_4_19_add_output.txt”

@checkpoint(key=lambdaargs,kwargs:'_'.join(map(str,[args[0],'bvalue',args[1],kwargs['arg3'],kwargs['arg4'],'output.txt')))deff(a,b,arg3=8,arg4='subtract'):# do something with the argsresult=(a-b)/arg3returnresult
@checkpoint(key=lambdaargs,kwargsstring.Template('{0}_bvalue_{1}_${arg3}_${arg4}_output.txt').substitute(kwargs).format(args))deff(a,b,arg3=8,arg4='subtract'):# do something with the argsresult=(a-b)/arg3returnresult
  1. 函数对象:这类似于lambda对象,但是key也可以接受命名函数。返回键的函数应该 接受表单名称的参数(args,kwargs),其中args是包含所有非关键字参数的元组,kwargs是字典 包含关键字及其值的。对于调用:f(3,4,arg3=19,arg4='add'),这将生成密钥名为'3_bvalue_4_19_add_output.txt'

    这种方法的优点是,如果处理的参数不能直接在模板中使用,则可以转换 它们可以添加到名字中。

defkey_namer(args,kwargs):return'_'.join(map(str,[args[0],'bvalue',args[1],kwargs['arg3'],kwargs['arg4'],'output.txt'))@checkpoint(key=key_namer)deff(a,b,arg3=8,arg4='subtract'):# do something with the argsresult=(a-b)/arg3returnresult

important注意:检查函数时,请记住根据您的 模板规范。尽管第三个参数arg3可以在不说arg3=19的情况下发送,但是模板不会接收arg3,因为我们 依赖与模板中匹配的关键字名称。

泡菜机/非泡菜机

pickler必须具有以下定义:

defmy_pickler(f,object):# f is an open file descriptorsave_to_f(object)pass

取消勾选者必须具有以下定义:

defmy_unpickler(f):# f is an open file descriptorobjec=load_object(f)returnobject

这些可以是围绕numpy.loadtxt、pandas.dataframe.to_csv的包装器, csv中的pandas.dataframe.from,以及更多这样的序列化函数。使用它们 使用这些实用函数来加载/保存numpy/pandas对象是 最重要的用途c用于昂贵的数值计算。

刷新选项

关键字参数'refresh'如果设置为true,则忽略缓存并重新计算函数。在一个包含多个步骤的过程中,可以使用 只刷新那些需要刷新的东西。虽然可以直接指定true/false,但更方便的方法是收集 将不同函数的值刷新到单个文件中,并在其中设置它们。

刷新可以作为布尔选项或函数传递。

当收集刷新值以更好地管理何时以及要刷新哪些函数时,需要使用 刷新的函数参数有以下几个原因。

例如,如果我有一个在输入x上运行的进程,作为一个步骤序列,该进程为y1=f1(x1)、y2=f2(y1)和yn=fn(yn-1)。检查站 装饰可以采用以下形式:

importdefs@checkpoint(key=key_namer,refresh=defs.TASK1_REFRESH)deff1(x1):y1=do_something(x1)returny1@checkpoint(key=key_namer,refresh=defs.TASK2_REFRESH)deff2(y1):y2=do_something(y1)returny2@checkpoint(key=key_namer,refresh=defs.TASK3_REFRESH)deff3(y2):y3=do_something(y2)returny3

现在,可以在其他地方使用这些定义(例如defs.py或main.py)独立控制这些函数:

# defs.pyimportos# Caveat: defs.py should contain a mutable object like a dict or a list.refresh_dict={}refresh_dict['task1']=Truerefresh_dict['task2']=os.environ['TASK2_REFRESH_OPTION']refresh_dict['task3']=True# main.pyimportdefsifsys.argv[1]=='task1':defs.refresh_dict['task1']=Falseifsys.argv[1]=='task3':defs.TASK1_REFRESH['task3']=True

警告1

在python模块(比如defs.py)中使用诸如refresh=true这样的不可变变量收集刷新选项时, 如果需要在运行时更改它们,则需要小心:

importdefs# NOT from defs import REFRESHdefs.REFRESH=True# NOT REFRESH = True

在python中,模块是对象,执行import defs将提供对模块的引用,并且变量refresh 可以在模块中使用defs.refresh=true进行更改。不过,defs import refresh中的为我们提供了一个参考 对于不可变的,在更改时生成其本地副本,而不更改模块变量。

警告2

通过命令行选项等更改刷新选项时,最好使用lambda函数作为

# module.pyimportdefs@checkpoint(...,refresh=lambda:defs.REFRESH)defmyfunc():pass

由于默认值是在定义时计算的,并使用lambda绑定到参数, (或一些可变的)我们确保获取refresh的当前值。

贡献

  1. 检查打开的问题或打开一个新的问题,开始围绕功能想法或错误的讨论。
  2. 在github上分叉the repository,开始对master分支(或其分支)进行更改。
  3. 编写一个测试,显示错误已修复或功能按预期工作。
  4. 发送一个pull请求并对维护程序进行bug操作,直到它被合并并发布。:)请确保将自己添加到AUTHORS

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
内存Java正在运行。jar heapdump错误   java如何在安卓画布中弯曲文本区域?   java如何在Gdx 安卓游戏编程中获得矩形的真实触碰位置?   找不到java Spring MVC控制器   在Java中使用双重检查锁定单例扩展类   java在高效的时间和内存中动态执行insert(索引、数据)、delete(索引)、getAt(索引)操作。   java 安卓 Toast和视图帮助   java协议缓冲区:从文件中读取所有序列化消息   java如何在Jackson中为参数化接口类型执行通用自定义反序列化程序   与简单的空检查相比,使用(平面)映射的java优势是什么?   异步方法seam中的java Get contextparam   jar使用相同的java运行时运行另一个java程序   java访问Spring批处理中的作业参数   java给定字符串为空或null   在h2数据库1.4中找不到java类“org.h2.fulltext.FullTextLucene”。*不适用于Lucene Core 4*   java Spring Boot在使用@enableSync时不响应任何请求   java错误:在bash上找不到或加载主类pj2   “返回对象”和“返回(对象)”之间的Java差异   java Android开发:如何使用onKeyUp?