超时装饰器

wrapt-timeout-decorator的Python项目详细描述


wrapt_timeout_decorator

pypi statuslicensemaintenancejupyter

构建状态codecov statusbetter code维修性snyk security

有很多超时修饰符-在与类、方法一起使用时,它关注的是正确性, 类方法、静态方法等,同时保留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下测试 ,自动每日生成和监视



在线试用

您可以使用"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 test
0
# normal install
python setup.py install
# test without installing
python setup.py test
1

使用信号的注意事项

正如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 test
2

嵌套超时

由于每个进程在unix上只有一个报警信号,因此需要对嵌套超时使用use_signals=false。 最外面的装饰或者可能使用信号,所有嵌套的装饰器都需要使用use_signals=false(默认值) 您可以在 jupyter

# normal install
python setup.py install
# test without installing
python setup.py test
3
# normal install
python setup.py install
# test without installing
python setup.py test
4

替代例外

指定在超时时引发的备用异常:

# normal install
python setup.py install
# test without installing
python setup.py test
5

参数

# normal install
python setup.py install
# test without installing
python setup.py test
6

覆盖参数

以dec和use开头的decorator参数可以被同名的kwargs覆盖:

# normal install
python setup.py install
# test without installing
python setup.py test
7

多线程

默认情况下,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 test
8 < div >

警告

确保在超时的多处理策略情况下,函数不返回不能返回的对象 被pickle,否则它将无法在主进程和子进程之间编组它。为了覆盖更多的案件, 我们使用多进程和dill,而不是多进程和pickle。

由于信号在Windows上不起作用,因此无论您设置了什么,它在默认情况下都会被禁用。

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

推荐PyPI第三方库


热门话题
java限制C++代码访问JNI中的某些类   Android上的java DateFormat:不可解析的日期   通过json进行java迭代,并为其他请求调用多个API   Netbeans中的java JavaFX项目引发异常“输入流不能为null”   多线程Java newFixedThreadPool解释   |在java字符串中无法识别。split()方法   Java中的原始包装器类是否被视为引用类型?   Java swing。如何在intellij idea GUI设计工具中重写组件方法   数组乘矩阵   java将30GB的XML文件分割成小块XML   java通过一棵树递归找到一个节点,并返回指向该节点的路径   java如何将可观察的<Observable<List<T>>转换为可观察的<List<T>>   使用java在web服务器上更改php文件中的字符串?   java希望开发像tomcat这样的servlet容器   java希望提高编程的数学技能