2016-04-26 17 views
1

Ich habe eine Funktion, die versucht, eine Liste von Parametern mit ftp zu verbinden und verbindet sich mit dem ersten Server, der es könnte.Wie komme ich mit Aussage zurück?

def connect(params): 
    for user, passw, host in params: 
     try: 
      import pdb;pdb.set_trace() 
      with FTPHost(host, user, passw) as h: 
       return h 
     except FTPError as e: 
      logger.debug("Can't connect to ftp error is {}".format(e)) 
    else: 
     raise Exception(
      "Can't connect to ftp server with none of the {}".format(params) 
     ) 

Weitere in Code Ich versuche, etwas wie das

host = connect(*args) 
host.walk() 

Aber gleich nach der Rückkehr die Verbindung geschlossen wird. Das ist wahrscheinlich, wie es funktionieren sollte, denke ich, obwohl ich hoffte, dass es nicht würde. Aber jetzt weiß ich nicht wirklich, wie man Versuche der Verbindung von der Anwendungslogik richtig kapselt.

Ich meine sicher könnte ich dies in Übertragungsstil Fortsetzung ändern (dies ist für die korrekte Name, nicht wahr?)

def connect(params, some_application_function): 
    for user, passw, host in params: 
     try: 
      import pdb;pdb.set_trace() 
      with FTPHost(host, user, passw) as host: 
       some_application_function(host) 
     except FTPError as e: 
      logger.debug("Can't connect to ftp error is {}".format(e)) 
    else: 
     raise Exception(
      "Can't connect to ftp server with none of the {}".format(params) 
     ) 

Aber das scheint weniger lesbar. Gibt es noch andere Möglichkeiten?

+0

Nicht direkt auf Ihre Frage, aber es scheint komisch, einen Kontextmanager in try/except zu packen - warum nicht "__enter__" und "__exit__' anpassen? – timgeb

+0

Einstellen wo? FTPHost ist eine Bibliothek. Nicht in meiner Kontrolle. Entschuldigung, dass ich das nicht ausdrücklich angegeben habe – user1685095

+0

Es ist nicht außerhalb Ihrer Kontrolle, es gibt immer das Adaptermuster für Bibliotheken, die nicht genau das tun, was Sie wollen, aber fast :) Wie auch immer, Entschuldigung für die Ablenkung. – timgeb

Antwort

0

Ich würde wahrscheinlich Ihre connect Funktion in einen Kontext-Manager konvertieren selbst, die Ihren FTPHOST Kontext-Manager Magie Methoden intern aufruft:

class FTPConnector: 
    def __init__(self, params): 
     self.params = params 
    def __enter__(self): 
     for user, passw, host in params: 
      try: 
       # import pdb;pdb.set_trace() # not sure what you want to do with that... 
       self.h_context = FTPHost(host, user, passw) 
       return self.h_context.__enter__() 
      except FTPError as e: 
       logger.debug("Can't connect to ftp error is {}".format(e)) 
     else: 
      raise Exception(
       "Can't connect to ftp server with none of the {}".format(params) 
      ) 
    def __exit__(self, exc_type, exc_value, traceback): 
     return self.h_context.__exit(exc_type, exc_value, traceback) 

Jetzt können Sie dies in Ihrer Hauptfunktion ausführen:

with FTPConnector(params) as host: 
    host.walk() 
    # do something useful with the connection here 

# here the connection gets closed again 
+0

Ich verkompliziere die Dinge. Solange Sie keine zusätzliche Funktionalität in die Methoden "__enter__" oder "__exit__" implementieren möchten, sollte die Antwort von * Te-jé Rodgers * auch in Ordnung sein. –

+0

Das ist, was ich hier tat, nur mit einfachen Kontext-Manager Dekorateur – user1685095

1

Vielleicht verschieben Sie die With-Anweisung nach außerhalb der Connect-Funktion?

def connect(params): 
    for user, passw, host in params: 
     try: 
      import pdb;pdb.set_trace() 
      return FTPHost(host, user, passw) 
     except FTPError as e: 
      logger.debug("Can't connect to ftp error is {}".format(e)) 
    else: 
     raise Exception(
      "Can't connect to ftp server with none of the {}".format(params) 
     ) 

def main(): 
    with connect(params) as h: 
     do_something(h) 
+0

Sie können keine einfache Funktion in der Anweisung 'with' verwenden. Das funktioniert nicht! –

+0

@ byte-commander Solange FTPHost '__enter__' und' __exit__' implementiert, funktioniert das in der Tat, da die FTPHost-Instanz selbst der Kontextmanager ist. Sie können dies selbst überprüfen, indem Sie das Ergebnis von 'open' aus einer einfachen Funktion zurückgeben und eine with-Anweisung für diese einfache Funktion verwenden. –

+0

Ah, du hast Recht. Entschuldigung, das war meine Schuld. –

Verwandte Themen