Skip to main content
 首页 » 编程设计

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

2025年05月04日15youxin

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

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当那个项目停止时。