2016-03-31 13 views
0

Ich muss Dateianhänge von E-Mail-Nachrichten lesen. Ich wollte Kontext-Manager für das Ressourcenmanagement verwenden (Verbindung geschlossen werden soll)So verwenden Sie den Kontextmanager mit Ausnahmen

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

Also, was diese Funktion tun sollte, ist versuchen, um einen E-Mail-Server zu verbinden, wiederholen n-mal, wenn die Verbindung verweigert wurde, wenn ein anderer Socket-Fehler geschehen ist, dann reraise es. Wenn die Wiederholungsversuche erschöpft sind, dann reraise rejise error error. Nachdem der Verbraucher alle Dateien konsumieren würde, schließen Sie die Verbindung. Im Moment gibt es Generator hat keinen Fehler ergeben.

+0

Ist das der 'contextlib.contextmanager'? – timgeb

+0

@timgeb Ja, es ist – user1685095

+1

Wenn Sie die [die Dokumente] (https://docs.python.org/3.4/library/contextlib.html?highlight=contextmanager#contextlib.contextmanager) für 'contextmanager 'lesen, werden Sie Beachten Sie, dass die Manager-Funktion zuerst eine Setup-Aktion ausführen und dann dem Client-Code (dh dem Block nach der with-Anweisung) nachgeben und dann eine Bereinigung durchführen sollte. Die 'with'-Anweisung ist im Wesentlichen eine Art, Code innerhalb einer vorgegebenen Vorher-Nachher-Logik einzuordnen. In Ihrem Fall befindet sich die yield-Anweisung in einer 'for'-Schleife, was wahrscheinlich nicht das ist, was Sie wollen. – SwiftsNamesake

Antwort

0

Umstrukturieren Sie Ihre try-except-Klausel so, dass sie die Mindestanzahl an Dingen umfasst. In der Ausnahme-Klausel können Sie bei Bedarf continue, und wenn es nicht ausgelöst wird, sollten Sie break von der for-Schleife.

Verwandte Themen