2016-04-26 7 views
1

私は、ftpに接続するためにいくつかのパラメタのリストを試し、可能な最初のサーバに接続する機能を持っています。コード内でさらにwith文から復帰するには?

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

私はおそらく内部的にあなたのFTPHOSTコンテキストマネージャの魔法のメソッド呼び出しコンテキストマネージャ自体にあなたのconnect機能を変換します:

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

# here the connection gets closed again 

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) 

を今すぐあなたのメイン機能でこれを実行することができ

+0

私はものを複雑にしています。あなたが '__enter__'や' __exit__'メソッドに余分な機能を実装したくない限り、* Te-jéRodgers *の答えはうまくいくはずです。 –

+0

これは私がここで実際に行ったことです。単純なコンテキストマネージャデコレータ – user1685095

1

おそらくwith文をconnect関数の外に移動しますか?

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__'を実装している限り、FTPHostインスタンス自体がコンテキストマネージャであるため、これは実際に動作します。プレーン関数から 'open'の結果を返し、そのプレーン関数にwith文を使うことで自分自身をチェックすることができます。 –

+0

ああ、そうです。申し訳ありません、それは私のせいでした。 –

関連する問題