超时装饰器
wrapt-timeout-decorator的Python项目详细描述
wrapt_timeout_decorator
有很多超时修饰符-在与类、方法一起使用时,它关注的是正确性, 类方法、静态方法等,同时保留pycharm调试的回溯信息。
还有一个强大的eval函数,它甚至可以从类属性中读取所需的超时值。
它非常灵活,可以从python 2.7到python 3.x、pypy、pypy3甚至其他方言使用。
实现了两种超时策略:使用"信号"的普遍方法和使用多处理的第二种超时策略。 使用"signals"很简单,但也有一些令人讨厌的注意事项,请检查 使用信号的注意事项部分
因此,默认策略是使用多处理,但您也可以使用信号,您已经收到警告!
由于windows上缺少信号,或者对于信号不能b你唯一的选择就是多处理, 这是自动设置的。
在windows下,修饰的函数和结果需要是可拾取的。 为此,我们使用"多处理"和"dill"而不是"多处理"和"pickle",以便能够在更复杂的对象上使用这个装饰器。 与子流程的通信是通过"multiprocess.pipe"而不是"queue"来完成的,后者速度更快,而且可能也适用于amazon aws。
100%代码覆盖率 ,mypy静态类型检查,在 linux、osx、windows和wine下测试 ,自动每日生成和监视
- 在线试用
- 安装和升级
- 基本用法
- 与Windows一起使用
- 使用信号的注意事项
- 嵌套超时
- 可选异常
- 参数
- 覆盖参数
- 多线程
- 用作函数而不是装饰器
- 使用强大的评估功能
- 检测pickle错误
- 登录修饰函数
- 硬超时 或-何时开始超时?
- 需求
- 确认
- 贡献
- 报告问题
- 拉取请求
- 行为准则
- 许可证
在线试用
您可以使用"launch binder"徽章立即在jupyter笔记本中尝试,或者单击 这里
安装和升级
源代码:
# normal install python setup.py install # test without installing python setup.py test
VIA PIP最新版本:
# latest Release from pypi pip install wrapt_timeout_decorator # test without installing pip install wrapt_timeout_decorator --install-option test
VIA PIP最新开发版本:
# upgrade all dependencies regardless of version number (PREFERRED) pip install --upgrade https://github.com/bitranox/wrapt_timeout_decorator/archive/master.zip --upgrade-strategy eager # normal install pip install --upgrade https://github.com/bitranox/wrapt_timeout_decorator/archive/master.zip # test without installing pip install https://github.com/bitranox/wrapt_timeout_decorator/archive/master.zip --install-option test
via requirements.txt:
# Insert following line in Your requirements.txt: # for the latest Release: wrapt_timeout_decorator # for the latest Development Version : https://github.com/bitranox/wrapt_timeout_decorator/archive/master.zip # to install and upgrade all modules mentioned in requirements.txt: pip install --upgrade -r /<path>/requirements.txt
通过Python:
# for the latest Releasepython-mpipinstallupgradewrapt_timeout_decorator# for the latest Development Versionpython-mpipinstallupgradehttps://github.com/bitranox/wrapt_timeout_decorator/archive/master.zip
基本用法
importtimefromwrapt_timeout_decoratorimport*@timeout(5)defmytest(message):# this example does NOT work on windows, please check the section# "use with Windows" in the README.rstprint(message)foriinrange(1,10):time.sleep(1)print('{} seconds have passed'.format(i))if__name__=='__main__':mytest('starting')
与Windows一起使用
对于不耐烦的人:
您只需将修饰后的函数放入另一个模块,而不是主程序。
对于那些想潜得更深的人:
在windows上,主模块被再次导入(但是有一个名字!='main'),因为python正在尝试模拟 不支持分叉的系统上类似分叉的行为。多处理试图创建环境 通过使用不同的名称再次导入主模块,类似于主进程。所以你需要保护 您的程序的入口点,带有著名的"if'u name==''uu main':"
importlib_foodefsome_module():lib_foo.function_foo()defmain():some_module()# here the subprocess stops loading, because __name__ is NOT '__main__'if__name__='__main__':main()
是Windows操作系统的问题,因为Windows操作系统不支持"fork"
您可以在此处找到更多信息:
https://stackoverflow.com/questions/45110287/workaround-for-use-name-main-in-python-multiprocessing
https://docs.python.org/2/library/multiprocessing.html windows
由于main.py再次加载时使用的名称不同,但使用的是"\uuu main\uu",修饰函数现在指向不再存在的对象,因此需要将修饰类和函数放入另一个模块中。 一般来说(特别是在windows上),main()程序除了main函数之外不应该有任何东西,真正的事情应该发生在模块中。 我还用于将所有设置或配置放在不同的文件中,以便所有进程或线程都可以访问它们(并将它们放在一个地方,不要忘记在您喜爱的编辑器中键入提示和完成名称)
"dill"序列化程序还可以序列化主上下文,这意味着我们的示例中的对象被pickle到"\uu main\uu.lib\u foo"、"\uu main\uu.some\u module"、"\uu main\uu.main"等。 当使用"pickle"时,我们不会有这样的限制,其缺点是"pickle"不能序列化以下类型:
函数的结果,嵌套函数,lambdas,cell,method,unboundmethod,module,code,methodwrapper, dictproxy、methoddescriptor、getsetdescriptor、memberdescriptor、wrapperdescriptor、xrange、slice, 未实现,省略号,退出
额外的DILL支持:
保存并加载python解释器会话,保存并从函数和类中提取源代码,以交互方式诊断pickling错误
为了使用decorator支持更多的类型,我们选择dill作为序列化器,其缺点是方法和类不能在主上下文中进行修饰,而需要驻留在模块中。
你可以在这里找到更多信息: https://stackoverflow.com/questions/45616584/serialization-an-object-in-main-with-pickle-or-dill
计时: 因为生成需要一些未知的时间跨度(所有导入都需要重新完成!),您可以指定超时的开始时间,请阅读硬超时部分
请注意,由于某些未知的原因,可能在多进程中,在使用python 2.7的windows下根本无法修饰类方法
这里有一个在Linux上工作但在Windows上不工作的示例(在派生进程中找不到变量"name"和函数"sleep":
main.py:fromtimeimportsleepfromwrapt_timeout_decoratorimport*name="my_var_name"@timeout(5,use_signals=False)defmytest():# this example does NOT work on windows, please check the example below !# You need to move this function into a module to be able to run it on windows.print("Start ",name)foriinrange(1,10):sleep(1)print("{} seconds have passed".format(i))returniif__name__=='__main__':mytest()
下面是相同的示例,它将在Windows上运行:
# my_program_main.py:importlib_testdefmain():lib_test.mytest()if__name__=='__main__':main()
# normal install python setup.py install # test without installing python setup.py test0
# normal install python setup.py install # test without installing python setup.py test1
使用信号的注意事项
正如abager1999在他的博客中指出的那样,https://anobadger.wordpress.com/2018/12/15/python-signal-handlers-and-exceptions/" rel="nofollow">https://anobadger.wordpress.com/2018/12/15/python-signal-handlers-and-exceptions/ 使用信号和TimeoutException可能不是最好的主意,因为它可以在修饰函数中捕获。
当然,您可以使用自己的异常(派生自基本异常类),但代码可能仍然无法按预期工作- 请参阅下一个示例-您可以在 jupyter :
# normal install python setup.py install # test without installing python setup.py test2
嵌套超时
由于每个进程在unix上只有一个报警信号,因此需要对嵌套超时使用use_signals=false。 最外面的装饰或者可能使用信号,所有嵌套的装饰器都需要使用use_signals=false(默认值) 您可以在 jupyter :
# normal install python setup.py install # test without installing python setup.py test3
# normal install python setup.py install # test without installing python setup.py test4
替代例外
指定在超时时引发的备用异常:
# normal install python setup.py install # test without installing python setup.py test5
参数
# normal install python setup.py install # test without installing python setup.py test6
覆盖参数
以dec和use开头的decorator参数可以被同名的kwargs覆盖:
# normal install python setup.py install # test without installing python setup.py test7
多线程
默认情况下,timeout decorator使用信号来限制执行时间 给定函数的。如果您的函数是 不在主线程中执行(例如,如果它是 或者当操作系统不支持信号时(又称windows)。 对于这种情况,有一种可选的超时策略-使用多处理。 这是自动完成的,因此您不需要设置 使用信号=false 。 您可以通过将参数 use-signals=false 传递到超时来强制不在Linux上使用信号 用于测试的decorator函数。如果你的程序也应该在windows上运行,我建议在 Windows,因为Windows不支持分叉(请在"与Windows一起使用"一节中阅读更多内容)。 以下代码将在Linux上运行,但不在Windows上运行:
# normal install python setup.py install # test without installing python setup.py test8 < div >
警告
确保在超时的多处理策略情况下,函数不返回不能返回的对象 被pickle,否则它将无法在主进程和子进程之间编组它。为了覆盖更多的案件, 我们使用多进程和dill,而不是多进程和pickle。
由于信号在Windows上不起作用,因此无论您设置了什么,它在默认情况下都会被禁用。