我试图为sync和declare函数创建一个动态装饰器函数,它工作得很好,但我不能进一步使用yield value。
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
字符串
我已经看到了许多其他的方法来给yield赋值,但没有一个能解决我的问题,因为我还想进一步使用它。任何其他的解决方案也是受欢迎的。
2条答案
按热度按时间zlwx9yxi1#
上下文管理器协议(即
with
语句及其相关的特殊方法和contextlib
模块中的帮助函数),或者在本例中也是“context manager”,不是设计成并且不能使其本身作为“重试”机制工作。这意味着:上下文管理器,或者是用
contextlib.contextmanager
装饰器装饰的生成器,或者是具有__enter__
和__exit__
方法的成熟类,将只,并且只能通过语言的工作方式,将控制传递给with
语句的主体一次。对于contextmanager
装饰的生成器,这意味着它必须在其生命周期中运行yield
表达式一次。您应该使用外部
while
循环和不同设计的类,或者使用现成的重试库来实现您的目标。至于一个很好的第三方库,它实现了很多选项的重试,并且关心边缘情况,你可以尝试“tenacity”:https://github.com/jd/tenacity
5anewei62#
我很有毅力。谢谢大家的指导。
字符串