前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python函数超时,用装饰器解决

Python函数超时,用装饰器解决

作者头像
小歪
发布2018-07-25 15:40:41
2.3K0
发布2018-07-25 15:40:41
举报
文章被收录于专栏:Python爬虫与算法进阶

使用场景

我们在自定义一个函数后,会调用这个函数来完成我们想要的功能。 就拿爬虫来举例,你发送请求,服务器给你响应,但是有可能服务器没有给你任何数据,无论是他识别了爬虫、还是服务器繁忙什么原因,这个时候,你的爬虫就会一直等待响应,这个时候就会非常浪费资源,还会造成程序阻塞。

好在requests和scrapy有自定义timeout时间,例如:在requests中这样写

代码语言:javascript
复制
requests.post(url, headers=headers, data=data, proxies=proxies, timeout=15)

在scrapy自定义下载超时时间DOWNLOAD_TIMEOUT = 15

但是,以上所说的仅仅是爬虫,实际中还会有各种各样的情况,在大佬指点下我知道了一个超级好用的函数装饰器 func_timeout

这么好的项目竟然没有关注~

func_timeout

安装:pip install func_timeout

使用:在你的函数前加上装饰器,如下:

代码语言:javascript
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
from func_timeout import func_set_timeout

@func_set_timeout(1)
def task():
    while True:
        print('hello world')
        time.sleep(1)

if __name__ == '__main__':
    task()

output:

代码语言:javascript
复制
hello world
Traceback (most recent call last):
  File "/home/test_.py", line 13, in <module>
    task()
  File "/home/usr/python36/lib/python3.6/site-packages/func_timeout/dafunc.py", line 185, in <lambda>
    return wraps(func)(lambda *args, **kwargs : func_timeout(defaultTimeout, func, args=args, kwargs=kwargs))
  File "/home/usr/python36/lib/python3.6/site-packages/func_timeout/dafunc.py", line 101, in func_timeout
    raise FunctionTimedOut('', timeout, func, args, kwargs)
func_timeout.exceptions.FunctionTimedOut: Function task (args=()) (kwargs={}) timed out after 1.000000 seconds.

func_timeout将在指定的参数的线程中运行指定的函数,直到返回,引发异常或超时。如果存在返回或异常,则将正常返回。

可以看到使用方法很简单,直接加上想要的超时时间即可。但是会抛出异常,终止你的程序。官方提供的捕获异常方法。

代码语言:javascript
复制
from func_timeout import func_timeout, FunctionTimedOut

...

try:

    doitReturnValue = func_timeout(5, doit, args=('arg1', 'arg2'))

except FunctionTimedOut:
    print ( "doit('arg1', 'arg2') could not complete within 5 seconds and was terminated.\n")
except Exception as e:
    # Handle any exceptions that doit might raise here

多线程中使用

那么问题来了,在使用多线程时效果如何?

在做实验时,开启多个线程去执行任务,任务里有些是超时的,抛出错误后会终端主进程,也就是该程序关闭,可以使用异常捕获。如:

代码语言:javascript
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from func_timeout import func_set_timeout
import time
import func_timeout

@func_set_timeout(1)
def task():
    while True:
        print('hello world')
        time.sleep(1)


if __name__ == '__main__':
    try:
        task()
    except func_timeout.exceptions.FunctionTimedOut:
        print('task func_timeout')

output:

代码语言:javascript
复制
hello world
task func_timeout

这样就可以不用中断主程序,可以继续执行后面的任务,也可以在超时后加上重试等功能,这就看自己需要了。

最后给大家一个福利,最近发现一个Pycharm的配色,仿制Sublime的 ,看起来非常舒服,地址 simoncos/pycharm-monokai

如果有推荐的主题,欢迎留言指出 ~~~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python爬虫与算法进阶 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档