我试图为同步和异步函数创建一个动态装饰器函数,它工作正常,但我无法进一步使用收益值。
def retry(f) -> Any:
@contextmanager
def retry_context(*args):
# response = False
i = 0
response_ok = False
retries = DEFAULT_RETRIES
status_retries = DEFAULT_STATUS_RETRIES
retry_count = 0
while i < retries and response_ok is False:
retry_count = retry_count+1
yield response
i += 1
if response.status_code not in status_retries:
response_ok = True
logger.debug("Response {}".format(response))
if not response_ok:
logger.warning("Response ERROR: {}".format(response))
return response
def wrapper(*args, **kwargs) -> Any:
with retry_context(*args):
return f(*args, **kwargs)
async def async_wrapper(*args, **kwargs) -> Any:
with retry_context(*args):
return await f(*args, **kwargs)
if asyncio.iscoroutinefunction(f):
return async_wrapper
return wrapper
我已经看到了许多其他为收益分配价值的答案,但没有一个能解决我的问题,因为我也想进一步使用它。也欢迎任何其他解决方案。
上下文管理器协议(即
with
语句及其在 contextlib
模块中关联的特殊方法和辅助函数) - 未设计且不能单独用作“重试”机制。
这意味着:上下文管理器,无论是用
contextlib.contextmanager
装饰器装饰的生成器,还是带有 __enter__
和 __exit__
方法的成熟类,都只能并且只能通过语言工作的方式传递控制权一次到 with
语句的主体。对于 contextmanager
修饰的生成器,这意味着它必须 在其生命周期中运行一次 yield
表达式。
您应该使用具有不同设计类的外部
while
循环,或者使用现成的重试库来实现您的目标。