2016-03-31 5 views
0

メール添付ファイルを読む必要があります。私は(接続が閉じされなければならない)、リソース管理のためのコンテキストマネージャを使用していた例外でコンテキストマネージャを使用する方法

@contextmanager 
def some_f(): 
    conn = None 
    try: 
     for _ in xrange(CONNECTION_ERRORS_MAX): 
      try: 
       conn = POP3(self.pop3_host) 
       conn.user(self.pop3_user) 
       conn.pass_(self.pop3_password) 
       logger.debug('connected {}', conn.getwelcome()) 
       _, msg_ids, _ = conn.uidl() 
       yield (
        (msg_id, self.files_from_msg(conn, file_batch_id, msg_id)) 
        for msg_id, file_batch_id in 
        (ul.split(' ') for ul in msg_ids) 
        if not self.is_ignored(file_batch_id, msg_id) 
       ) 
      except socket.error as e: 
       if e.errno == errno.ECONNREFUSED: 
        pass 
       else: 
        raise e 
    finally: 
     if conn: 
      conn.quit() 

だから、別のソケットエラー場合、接続が拒否された場合には行うことになって、この機能は、電子メールサーバに接続しようとn回の再試行が何でありますかそれが起こった後、それを再評価します。再試行が尽きた場合は、接続拒否エラーを再発生させます。消費者がすべてのファイルを消費した後、接続を閉じます。 今はジェネレータがエラーを発生させませんでした。

+0

これは 'contextlib.contextmanager'ですか? – timgeb

+0

@timgebはいそれは – user1685095

+1

です。[docs](https://docs.python.org/3.4/library/contextlib.html?highlight=contextmanager#contextlib.contextmanager)の 'contextmanager'を読むと、マネージャー関数がまず何らかのセットアップアクションを実行してから、 'クライアント'コード(つまり、withステートメントの後のブロック)に出力してからクリーンアップを実行する必要があることを確認してください。 'with'ステートメントは、本質的に、あらかじめ定義された前後のロジック内でコードを挟む方法です。あなたのケースでは、yield文は 'for'ループの内側にあります。これはおそらくあなたが望むものではありません。 – SwiftsNamesake

答えて

0

try-except句を最小数の物を囲むように再構成します。 except句では、必要に応じてcontinueを指定できます。トリガされていない場合は、forループからbreakを指定する必要があります。

関連する問題