2016-03-29 13 views
1

'da iki kez kullanımı kullanma Bir contextmanager ile bazı try/except karmaşıklıklarını gizlemeye çalışıyorum. Burada kolay bir örnektir:contextmanager

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

anladığım gibi verim çağrıldığında Şimdi, ifadeye blok yürütülür. Benim durumumda, bu bir istisna oluşturuyorsa, mpd'ye yeniden bağlanıyorum. Bu yeniden bağlanma işleminden sonra yine with-block komutunu çalıştırabilir miyim?

Teşekkür

cevap

5

Kısa cevap Bir bağlam yöneticisinden iki kez verim olamaz. Yürütmeye çalıştığınız şeyi saran bir dekoratör kullanmayı düşünebilirsiniz ve pes etmeden önce belirli sayıda tekrar deneyip yeniden bağlarsınız. İşte önemsiz (üretim dışı kullanım) örnek sadece göstermek için:

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

Düzenleme: eklenmiş çağrı no-argüman durumunda, dekoratör için