python - Python 上下文管理器如何尝试执行代码?

标签 python exception try-catch yield contextmanager

我正在尝试编写一个小型上下文管理器,它会尝试重复执行一些代码,直到代码正常工作或直到进行了指定次数的尝试。我试图写这篇文章,但在让上下文管理器在屈服时处理问题时遇到了困难:

Exception RuntimeError: 'generator ignored GeneratorExit'

我应该如何编码?

import contextlib
import random

def main():

    with nolube():
        print(1 / random.randint(0, 1))

@contextlib.contextmanager
def nolube(
    tries = None # None: try indefinitely
    ):
    """
    Create a context for trying something repeatedly.
    """
    tries_done = 0
    rekt = True
    if tries is None:
        while rekt is True:
            try:
                yield
                rekt = False
            except:
                tries_done += 1
                pass
    else:
        while rekt is True and tries_done <= tries:
            try:
                yield
                rekt = False
            except:
                tries_done += 1
                pass

if __name__ == "__main__":
    main()

最佳答案

@contextlib.contextmanager 有一个非常清晰的契约;它只会恢复一次。它不能用于重新运行代码。

事实上,您根本无法使用上下文管理器来控制重复。您在这里需要一个循环,而不是上下文管理器。上下文管理器不控制 block ,仅在进入和退出时通知它。

使用 tenacity package * 代替;它提供了一个装饰器。装潢师wraps a function in a while True loop这将为您重新运行该功能。

您可以通过将 print() 语句移动到一个用 @retry 修饰的函数中,然后调用该函数来将其应用于您的案例:

import random
from tenacity import retry

@retry
def foo():
    print(1 / random.randint(0, 1))

def main():
    foo()

* 这个答案原本推荐retrying package但这是forked into a new package with updated API当那个项目停止时。

关于python - Python 上下文管理器如何尝试执行代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36740887/

相关文章:

python - 为什么我不能在一行中交换列表中的两个项目?

python - 分解适合 python 的随机森林分类?

c# - 将 try-catch 放入循环中,直到 try block 中的所有语句都执行完,没有任何异常,这是一种好习惯吗?

python - Python3 Try/Except block

javascript - 如何拒绝同步和异步代码函数中的 promise ?

python - 喘息模板字典变量查找

python - 如何使用 matplotlib 绘制 .txt 文件中的数据

java - 为什么自定义异常 java 类应该是最终的

java - 遇到意外文本时抛出什么异常?

java - 运行应用程序时出现 IllegalArgumentException。 (安卓)