如何使用具有异常的上下文管理器

时间:2016-03-31 13:28:40

标签: python exception-handling contextmanager

我需要从电子邮件中读取文件附件。我想使用上下文管理器进行资源管理(连接应该关闭)

@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次,然后重新加载它。如果重试尝试已用尽,则再次尝试连接拒绝错误。消费者将消耗所有文件后关闭连接。 现在它给发电机没有产生错误。

1 个答案:

答案 0 :(得分:0)

重构你的try-except子句,使其包围最少数量的事物。在except子句中,如果需要,您可以continue,如果没有触发,您应该从for循环中break