摄影:产品经理
好像是鱼子酱
程序员是一个需要持续学习的群体,如果你发现你现在写的代码跟你5年前的代码没什么区别,说明你掉队了。
我们在做Python开发时,经常使用一些第三方库,这些库很多年来持续添加了新功能。但我发现很多同学在使用这些第三方库时,根本不会使用新的功能。他们的代码跟几年前没有任何区别。
举个例子,使用Request发起HTTP请求,请求失败时,不管什么原因,原地重试最多3次。很多人主要有下面3种写法来重试。
常见的老方法
使用第三方库
这类同学会使用一些专业做重试的第三方库,例如tenacity。详见我的这篇文章:Tenacity——Exception Retry 从此无比简单
手动写装饰器
这类同学会使用装饰器,所以一般会手写装饰器从而复用,例如:
代码语言:javascript复制def retry(func):
def wrap(*args, **kwargs):
for _ in range(3):
try:
result = func(*args, **kwargs)
return result
except Exception as e:
print('报错了,重试')
return {}
return wrap
@retry
def make_request(url):
print('以下是发起请求的相关代码')
反复for循环
还有一些同学,写代码走的是野路子:
代码语言:javascript复制def login():
for i in range(10): # 重试10次
try:
resp = requests.get('某某URL')
return resp.json()
except Exception as e:
print(f'请求报错了,重试第{i}次')
continue
这类同学基本不会复用代码。代码里面要向N个url发起请求,他们就会在N个地方像上面这样写代码。
新的方法
这里我虽然说是新方法,但是这个方法应该至少在9年前就能用了。只是网上用的人比较少。我们可以使用requests自带的HTTPAdapter
来实现自动重试。当我们不关心具体报错是什么,只需要机械重试时,就可以使用这个方法:
import requests
from requests.adapters import HTTPAdapter, Retry
session = requests.Session()
retries = Retry(total=3, backoff_factor=1)
session.mount('http://', HTTPAdapter(max_retries=retries))
session.mount('https://', HTTPAdapter(max_retries=retries))
# 接下来使用session发起的所有请求,默认最多会重试3次
session.get('http://httpbin.org/delay/5', timeout=2)
session.get('https://www.kingname.info')
...
END