Мне нужно прочитать вложения файлов из сообщений электронной почты. Я хотел использовать менеджер контекста для управления ресурсами (соединение должно быть закрыто)Как использовать диспетчер контекста с исключениями
@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()
Так что эта функция должна сделать, это попытаться подключиться к серверу электронной почты, повторите п раз, если соединение было отказано, если другая ошибка сокета произошли затем ререйз. Если попытки повторной попытки исчерпаны, то повторное соединение отказалось от ошибки. После того, как потребитель будет потреблять все файлы с близким подключением. Прямо сейчас он дает генератору ошибку.
Это что, 'contextlib.contextmanager'? – timgeb
@timgeb да это – user1685095
Если вы читаете [документы] (https://docs.python.org/3.4/library/contextlib.html?highlight=contextmanager#contextlib.contextmanager) для 'contextmanager', вы будете что функция диспетчера должна сначала выполнить какое-либо действие по настройке, затем перейти к «клиентскому» коду (т. е. блоку после оператора with), а затем выполнить некоторую очистку; оператор 'with' является, по сути, способом сэндвич-кода в пределах определенной предопределенной логики до и после. В вашем случае оператор yield находится внутри цикла 'for', что, вероятно, не является тем, что вы хотите. – SwiftsNamesake