如何将yield值赋给变量

问题描述 投票:0回答:1

我试图为同步和异步函数创建一个动态装饰器函数,它工作正常,但我无法进一步使用收益值。

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

我已经看到了许多其他为收益分配价值的答案,但没有一个能解决我的问题,因为我也想进一步使用它。也欢迎任何其他解决方案。

python python-asyncio contextmanager
1个回答
0
投票

上下文管理器协议(即

with
语句及其在
contextlib
模块中关联的特殊方法和辅助函数) - 未设计且不能单独用作“重试”机制。

这意味着:上下文管理器,无论是用

contextlib.contextmanager
装饰器装饰的生成器,还是带有
__enter__
__exit__
方法的成熟类,都只能并且只能通过语言工作的方式传递控制权一次到
with
语句的主体。对于
contextmanager
修饰的生成器,这意味着它必须 在其生命周期中运行一次
yield
表达式。

您应该使用具有不同设计类的外部

while
循环,或者使用现成的重试库来实现您的目标。

© www.soinside.com 2019 - 2024. All rights reserved.