Python 在contextmanager中两次使用yield
我试图用contextmanager隐藏一些尝试/除外的复杂性。下面是一个简单的例子:Python 在contextmanager中两次使用yield,python,yield,contextmanager,mpd,Python,Yield,Contextmanager,Mpd,我试图用contextmanager隐藏一些尝试/除外的复杂性。下面是一个简单的例子: from contextlib import contextmanager import mpd mpdclient = mpd.MPDClient() mpdclient.connect("localhost", 6600) @contextmanager def mpdcontext(): try: yield except mpd.ConnectionError: mpdcl
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块
谢谢简单的回答是,你不能从上下文管理器中重复两次。你可以考虑使用一个装饰器来包装你试图执行的东西,并在放弃之前重试并重新连接一次。下面是一个简单的(非生产用途)示例,仅用于说明:
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()
编辑:在无参数的情况下添加了对decorator的调用