python实现装饰器带参数_装饰器带参数

装饰器带参数

装饰器携带参数,可以实现更加强大的装饰器,本篇教程以http请求重试场景来讲解如何编写带参数的装饰器。

1. 重试场景

假设这样一个场景,你写了一个函数,用来从一个API接口获取数据,那么你必须考虑网络问题,也许网关解析会出错,也许API接口压力太大,短时间内响应超时,面对这种情况,你的函数应该具备重试功能。

请求失败以后,暂停一定时间,再次发起请求,重试的次数必须是可设置的。你可以把这个功能在函数中实现,但可以肯定,这不是一个好方法,原因在于每一个这样的函数你都需要实现一遍,而且不同的函数访问不同的API,暂停的时间以及重试的次数都有可能不同。

这种请求,就非常适合用装饰器来解决

2. 带参数装饰器

from functools import wraps

def retry(retry_count=5, sleep_time=1):

def wrapper(func):

@wraps(func)

def inner(*args, **kwargs):

for i in range(retry_count):

try:

res = func(*args, **kwargs)

return res

except:

time.sleep(sleep_time)

continue

return None

return inner

return wrapper

这段代码一共嵌套着定义了3个函数,在讲解作用域的时候强调过,嵌套作用域是一个相对概念,在函数inner里可以访问更上层的局部作用域里的数据,retry_count是函数retry的一个参数,在inner里根据retry_count来决定重试的次数,只要发生了异常,就会重试。

3. 如何使用

写爬虫时,你不得不考虑网络因素,一次请求可能无法得到所需要的响应数据,这时就需要重试

class HttpCodeException(Exception):

pass

@retry()

def get_html(url):

headers = {

'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.87 Mobile Safari/537.36',

'Host': 'movie.douban.com',

'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',

'Referer': 'https://movie.douban.com/top250?start=25&filter='

}

res = requests.get(url, headers=headers)

if res.status_code != 200:

raise HttpCodeException

return res.text

这段代码是我编写过的一个爬虫的一小部分,在其他场景下,只要涉及到重试,都可以使用我写的这个装饰器。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值