使用场景
我们在自定义一个函数后,会调用这个函数来完成我们想要的功能。 就拿爬虫来举例,你发送请求,服务器给你响应,但是有可能服务器没有给你任何数据,无论是他识别了爬虫、还是服务器繁忙什么原因,这个时候,你的爬虫就会一直等待响应,这个时候就会非常浪费资源,还会造成程序阻塞。
好在requests和scrapy有自定义timeout
时间,例如:在requests中这样写
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
如果有推荐的主题,欢迎留言指出 ~~~