2016-04-26 7 views
1

У меня есть функция, которая пробует некоторый список параметров для подключения к ftp и подключается к первому серверу, который он мог.Как вернуться с заявлением?

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

Далее в коде я пытаюсь что-то вроде этого

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

Но сразу же после возврата соединение закрывается. Вероятно, это должно сработать, хотя я надеялся, что это не так. Но теперь я не знаю, как правильно инкапсулировать процессы подключения из прикладной логики.

Я имею в виду, конечно, я мог бы изменить это в продолжение прохождения стиль (это правильное название для этого, не так ли?)

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

Но это кажется менее читаемым. Есть ли другие варианты?

+0

Не обращайтесь непосредственно к своему вопросу, но кажется странным обернуть контекстный менеджер в try/except - почему бы не настроить '__enter__' и' __exit__'? – timgeb

+0

Настроить где? FTPHost - это библиотека. Не под моим контролем. Извините, что я не сказал, что явно – user1685095

+0

Это не из-под вашего контроля, всегда есть шаблон адаптера для библиотек, которые не делают именно то, что вы хотите, но почти :) В любом случае, извините за то, что вы отвлекаетесь. – timgeb

ответ

0

я бы, вероятно, преобразовать connect функции в самом менеджеру контекста, который внутренне вызывает магические методы контекста вашего FTPHost управляющие:

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) 

Теперь вы можете запустить это в вашей основной функции:

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

# here the connection gets closed again 
+0

Я слишком усложняю вещи. Если вы не хотите внедрять дополнительные функции в методы '__enter__' или' __exit__', ответ * Te-jé Rodgers * также должен быть точным. –

+0

Вот что я на самом деле сделал здесь, только используя простой декоратор-менеджер контекста – user1685095

1

Может быть, сдвинуть оператор WITH вне функции подключения?

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

Вы не можете использовать простую функцию в инструкции 'with'. Это не работает! –

+0

@ byte-commander Пока FTPHost реализует '__enter__' и' __exit__', этот _does_ действительно работает, поскольку сам экземпляр FTPHost является менеджером контекста. Вы можете проверить сами, вернув результат 'open' из простой функции и используя оператор with для этой простой функции. –

+0

Ах, ты прав. Извините, это была моя ошибка. –