2016-03-29 10 views
1

Ich versuche, einige versuchen/außer Komplexität mit einem Contextmanager zu verstecken. Hier ist ein einfaches Beispiel:Verwendung der Ausbeute zweimal im 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() 

Jetzt, da ich verstanden, der Block in der with-Anweisung ausgeführt wird, wenn Ausbeute aufgerufen wird. In meinem Fall, wenn dies eine Ausnahme auslöst, verbinde ich mich erneut mit mpd. Kann ich den With-Block nach diesem Reconnect irgendwie wieder ausführen?

Dank

Antwort

5

Kurze Antwort ist, dass Sie nicht zweimal aus einem Kontext-Manager ergeben können. Sie könnten einen Dekorator in Betracht ziehen, der das, was Sie ausführen möchten, umschließt und eine bestimmte Anzahl von Versuchen wiederholt und erneut verbindet, bevor Sie aufgeben. Hier ist ein triviales (nicht-produktiver Einsatz) Beispiel nur zur Veranschaulichung:

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

bearbeiten: hinzugefügt Aufruf Dekorateur, in dem kein Argument Fall