2016-03-29 10 views
1

コンテキストマネージャーでいくつかのtry/except複雑さを隠そうとしています。ここでは簡単な例です:コンテキストマネージャーで2回の歩留まりを使用する

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() 

私は理解されるように歩留まりが呼び出されたときに今、ステートメントを使用して、ブロックが実行されます。私の場合、例外が発生すると、mpdに再接続します。この再接続の後、私は何とかwith-blockを何とか実行できますか?

ありがとうございました

答えて

5

簡単な答えは、コンテキストマネージャから2回は返されません。実行しようとしているものをラップするデコレータを使うことを検討し、あきらめる前に設定した回数だけ再試行して再接続します。ここでは些細な(非生産使用)の例では、ちょうど説明します

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() 

編集は:追加の呼び出しは引数なしの場合には、デコレータし

関連する問題