python给函数设置超时时间_使用timeout-decorator为python函数义务设置超时时间

需求靠山

在python代码的实现中,若是我们有一个需要执行时间跨度非常大的for循环,若是在中心的某处我们需要准时住手这个函数,而不住手整个程序。那么开端的就可以想到两种方案:第一种方案是我们先预估for循环或者while中的每一步所需要的运行时间,然后设定在到达某一个迭代次数之后就自动退出循环;第二种方案是,在需要设置超时义务的前方引入超时的装饰器,使得跨越指准时间之后自动退出函数执行。这里我们将针对第二种方案,举行睁开先容。

timeout-decorator的安装

在pypi的尺度库中也包罗有timeout-decorator模块,因此可以通过pip来直接安装:

[dechin@dechin-manjaro timeout]$ python3 -m pip install timeout_decorator

Collecting timeout_decorator

Downloading timeout-decorator-0.5.0.tar.gz (4.8 kB)

Building wheels for collected packages: timeout-decorator

Building wheel for timeout-decorator (setup.py) ... done

Created wheel for timeout-decorator: filename=timeout_decorator-0.5.0-py3-none-any.whl size=5029 sha256=279f8585a08d5e5c87de887492169d1a81e02060c8ea3b62fdd6f062b7f83601

Stored in directory: /home/dechin/.cache/pip/wheels/38/05/4e/161d1463ca145ec1023bd4e5e1f31cbf9239aa8f39a2a2b643

Successfully built timeout-decorator

Installing collected packages: timeout-decorator

Successfully installed timeout-decorator-0.5.0

设置一个超时义务

这里我们先展示示例代码,再睁开先容其中各个模块的寄义:

# timeout_test1.py

from tqdm import trange

import sys

import time

import timeout_decorator

@timeout_decorator.timeout(int(sys.argv[2]))

def test():

if sys.argv[1] == '--timeout':

for i in trange(3):

time.sleep(1)

print ('>>> {} seconds passed.'.format(i+1))

return 0

if __name__ == '__main__':

try:

test()

except Exception as e:

print ('Timeout Error Catched!')

print (e)

print ("Timeout Task Ended!")

timeout-decorator装饰器的使用

该超时模块接纳装饰器的形式来举行挪用,使用时先import该模块,然后在需要设置准时义务的函数前添加@timeout_decorator.timeout(3)即可,这里括号中的3示意超时时间设置为3s,也就是3s后该函数就会住手运行。前面写过一篇博客先容若何自界说一个装饰器,感兴趣的读者可以自行阅读。在上述的用例中,为了使得超时时间的界说加倍天真,我们采取了从用户输入获取参数的方案,具体内容参考下一章节的先容。

通过sys获取timeout参数

在上述用例的装饰器中,我们看到了int(sys.argv[2])这样的一个参数,这个参数的意思是用户输入命令行的第三个用空格离隔的参数。举例子说,若是用户执行了python3 test.py -t 1,那么这里就会发生三个输入参数:argv[0]就是test.py,argv[1]就是-t,argv[2]就是1,是一个数组的花样。需要注重的是,argv数组的每一个元素都是字符串花样,若是需要使用数字需要先举行花样转换。这里针对于超时义务的处置,我们指定的执行策略为类似python3 task.py --timeout 5的花样,--timeout后面的数字示意义务执行超时的秒数。若是输入变量花样不正确,或者不满足3个以上的变量输入要求,或者第二个参数不是--timeout,都有可能运行报错。

异常捕捉

在界说好超时义务之后,若是达到了设定好的超时时间,系统会给出timeout_decorator.timeout_decorator.TimeoutError报错并竣事程序运行。然则我们这里设置超时义务的目的实在是希望在超时义务的函数到达指准时间之后退出,然则不影响其他模块程序的运行,因此这里我们需要对程序给出的报错举行异常捕捉,而且转达与抑制该异常。对照简单的方案就是接纳except Exception as e的方式,一样平常Exception最好可以指向指定的报错类型,而不是通用的Exception处置,这有可能带来其他的一些风险。

用例测试

以下根据输入参数的差别,我们先划分为几个模块来剖析输出效果以及缘故原由。

超时义务为2s

[dechin@dechin-manjaro timeout]$ python3 timeout_test.py --timeout 2

0%| | 0/3 [00:00, ?it/s]>>> 1 seconds passed.

33%|█████████████▋ | 1/3 [00:01<00:03, 1.99s/it]

Timeout Error Catched!

'Timed Out'

Timeout Task Ended!

效果剖析:由于我们在程序中给定了一个一共会执行3s的义务,而这里在命令行中我们将超时时间设置为了2s,因此还没执行完程序就抛出并捕捉了异常,乐成打印了Timeout Task Ended!这一超时义务之外的义务。

超时义务为3s

[dechin@dechin-manjaro timeout]$ python3 timeout_test.py --timeout 3

0%| | 0/3 [00:00, ?it/s]>>> 1 seconds passed.

33%|█████████████▋ | 1/3 [00:01<00:02, 1.00s/it]>>> 2 seconds passed.

67%|███████████████████████████▎ | 2/3 [00:02<00:01, 1.50s/it]

Timeout Error Catched!

'Timed Out'

Timeout Task Ended!

效果剖析:由于我们在程序中给定了一个一共会执行3s的义务,虽然在命令行的输入参数中我们给定了3s的执行时间,然则最终程序照样没有执行竣事并抛出了异常。这是由于sleep(1)并不是精准的1s,也许是1.0000001然则这超出来的时间也会对最终执行的总时间发生影响,况且另有其他模块程序所导致的overlap,因此最后也没有执行完成。而且从进度条来看,上面一个章节中时间设置为3s的时刻,实在也只是完成了33%的义务而不是67%的义务,这也是相符我们的预期的。

超时义务为4s

[dechin@dechin-manjaro timeout]$ python3 timeout_test.py --timeout 4

0%| | 0/3 [00:00, ?it/s]>>> 1 seconds passed.

33%|█████████████▋ | 1/3 [00:01<00:02, 1.00s/it]>>> 2 seconds passed.

67%|███████████████████████████▎ | 2/3 [00:02<00:01, 1.00s/it]>>> 3 seconds passed.

100%|█████████████████████████████████████████| 3/3 [00:03<00:00, 1.00s/it]

Timeout Task Ended!

效果剖析:由于我们在程序中给定了一个一共会执行3s的义务,而在参数输入时设置了4s的超时时间,因此最终义务可以顺遂执行完成。这里为了验证上面一个小章节中提到的overlap,我们可以实验使用系统自带的时间测试模块来测试,若是该程序执行完成之后,一共需要若干的时间:

[dechin@dechin-manjaro timeout]$ time python3 timeout_test.py --timeout 4

0%| | 0/3 [00:00, ?it/s]>>> 1 seconds passed.

33%|█████████████▋ | 1/3 [00:01<00:02, 1.00s/it]>>> 2 seconds passed.

67%|███████████████████████████▎ | 2/3 [00:02<00:01, 1.00s/it]>>> 3 seconds passed.

100%|█████████████████████████████████████████| 3/3 [00:03<00:00, 1.00s/it]

Timeout Task Ended!

real 0m3.167s

user 0m0.147s

sys 0m0.017s

这里我们就可以看到,实在额定为3s的义务,执行完成需要约3.2s的现实时间,多出来的时间就是所谓的overlap。

总结提要

函数的超时设置是一个对照小众使用的功效,可以用于义务的暂停(并非截断)等场景,而且配合上面章节提到的异常捕捉和参数输入来使用,会使得义务加倍优雅且合理。

版权声明

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值