python - 如何避免 python 装饰器函数中的名称冲突
问题描述
我想编写一个python装饰器,以便再次运行引发异常的函数,直到它成功,或者在放弃之前达到最大尝试次数。
像这样:
def tryagain(func):
def retrier(*args,**kwargs,attempts=MAXIMUM):
try:
return func(*args,**kwargs)
except Exception as e:
if numberofattempts > 0:
logging.error("Failed. Trying again")
return retrier(*args,**kwargs,attempts=attempts-1)
else:
logging.error("Tried %d times and failed, giving up" % MAXIMUM)
raise e
return retrier
我的问题是我想要保证无论 kwargs 包含什么名称,都不会与用于表示尝试次数的名称发生冲突。
attempts
但是,当函数本身作为关键字参数时,这不起作用
@tryagain
def other(a,b,attempts=c):
...
raise Exception
other(x,y,attempts=z)
在此示例中,如果运行 other,它将运行 z 次而不是 MAXIMUM 次(请注意,要发生此错误,必须在调用中显式使用关键字参数!)。
解决方案
您可以指定装饰器参数,类似于以下内容:
import logging
MAXIMUM = 5
def tryagain(attempts=MAXIMUM):
def __retrier(func):
def retrier(*args,**kwargs):
nonlocal attempts
while True:
try:
return func(*args,**kwargs)
except Exception as e:
attempts -= 1
if attempts > 0:
print('Failed, attempts left=', attempts)
continue
else:
print('Giving up')
raise
return retrier
return __retrier
@tryagain(5) # <-- this specifies number of attempts
def fun(attempts='This is my parameter'): # <-- here the function specifies its own `attempts` parameter, unrelated to decorator
raise Exception(attempts)
fun()
推荐阅读
- javascript - 如何在本机反应中创建具有xy坐标的动态数组
- python - 如何在 Python 硒测试中处理 Bootstrap3 模态弹出消息?
- c - 如何通过指针从数组中删除元素
- spring-boot - Spring cloud stream中BROKER rabbitMq宕机时如何处理?
- amazon-ec2 - 是否可以在 Bitbucket Pipelines 上使用“pm2 deploy production”进行部署?
- java - 在春季启动单元测试@Async
- botframework - 在 ms 团队中获取团队成员时出错
- java - 没有元素时如何重构for循环方法以中断
- ruby-on-rails - rails:一页上的多个控制器操作
- c# - SonarQube 规则集存在于项目中,但在代码分析中没有生成任何内容