【问题标题】:Using yield twice in contextmanager在 contextmanager 中使用两次 yield
【发布时间】:2016-07-17 16:26:54
【问题描述】:

我正在尝试使用上下文管理器隐藏一些 try/except 复杂性。这是一个简单的例子:

from contextlib import contextmanager
import mpd

mpdclient = mpd.MPDClient()
mpdclient.connect("localhost", 6600)

@contextmanager
def mpdcontext():
  try:
    yield
  except mpd.ConnectionError:
    mpdclient.connect("localhost", 6600)

with mpdcontext():
  mpdclient.status()

with mpdcontext():
  mpdclient.lsinfo()

现在,据我了解,with 语句中的块是在调用 yield 时执行的。就我而言,如果这引发异常,我会重新连接到 mpd。重新连接后,我可以以某种方式再次执行 with-block 吗?

谢谢

【问题讨论】:

    标签: python yield contextmanager mpd


    【解决方案1】:

    简短的回答是您不能从上下文管理器中获得两次。您可以考虑使用一个装饰器来包装您尝试执行的内容,并在放弃之前重试和重新连接一定次数。这是一个简单的(非生产用途)示例,只是为了说明:

    import mpd
    import functools
    
    HOST = "localhost"
    PORT = 6600
    mpdclient = mpd.MPDClient()
    mpdclient.connect(HOST, PORT)
    
    def withreconnect(retries=1):
        def _wrapper(func):
            @functools.wraps(func)
            def wrapped(*args, **kwargs):
                for _ in range(retries + 1): # Loop retries + first attempt
                    try:
                        return func(*args, **kwargs)
                    except mpd.ConnectionError:
                        mpdclient.connect(HOST, PORT)
            return _wrapped
        return wrapped
    
    @withreconnect() # Reconnect 1 time, default
    def status():
        mpdclient.status()
    
    @withreconnect(retries=3) # Reconnect 3 times
    def lsinfo():
        mpdclient.lsinfo()
    

    编辑:在无参数情况下添加了对装饰器的调用

    【讨论】:

      猜你喜欢
      • 2011-02-16
      • 1970-01-01
      • 2017-05-04
      • 2015-03-02
      • 2020-10-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-18
      • 2016-05-04
      相关资源
      最近更新 更多