【发布时间】:2016-03-31 13:28:39
【问题描述】:
我需要从电子邮件中读取文件附件。我想使用上下文管理器进行资源管理(应该关闭连接)
@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 次,然后重新启动它。如果重试尝试用尽,则重新引发连接被拒绝错误。消费者消费完所有文件后关闭连接。 现在它给出了生成器没有产生错误。
【问题讨论】:
-
那是
contextlib.contextmanager吗? -
如果您阅读the docs 中的
contextmanager,您会看到管理器功能应该首先执行一些设置操作,然后让给“客户端”代码(即with 语句),然后执行一些清理;with语句本质上是一种将代码夹在一些预定义的前后逻辑中的方式。在您的情况下,yield 语句位于for-loop 内,这可能不是您想要的。 -
您应该展示您打算如何使用该上下文管理器。
标签: python exception-handling contextmanager