用`with`语句

时间:2016-09-22 12:51:07

标签: python imap with-statement imaplib

我希望有一个代表IMAP连接的类,并将其与with语句一起使用,如下所示:

class IMAPConnection:
    def __enter__(self):
        connection = imaplib.IMAP4_SSL(IMAP_HOST)

        try:
            connection.login(MAIL_USERNAME, MAIL_PASS)
        except imaplib.IMAP4.error:
            log.error('Failed to log in')

        return connection

    def __exit__(self, type, value, traceback):
        self.close()

with IMAPConnection() as c:
    rv, data = c.list()
    print(rv, data)

由于IMAPConnections没有属性close,自然会失败。如何在__exit__语句完成后存储连接并将其传递给with函数?

2 个答案:

答案 0 :(得分:4)

您需要在对象属性中存储连接。像这样:

class IMAPConnection:
    def __enter__(self):
        self.connection = imaplib.IMAP4_SSL(IMAP_HOST)

        try:
            self.connection.login(MAIL_USERNAME, MAIL_PASS)
        except imaplib.IMAP4.error:
            log.error('Failed to log in')

        return self.connection

    def __exit__(self, type, value, traceback):
        self.connection.close()

您还希望为您的班级实施list方法。

编辑:我刚才意识到你的实际问题是什么。当您执行时with SomeClass(*args, **kwargs) as c c不是__enter__方法返回的值。 cSomeClass的实例。这是您从__enter__返回连接并且假设c是连接的问题的根源。

答案 1 :(得分:0)

您需要在__exit__()课程中实施IMAPConnection功能。

__enter__()块中执行代码之前调用

with函数,同时退出__exit__()块时调用with

以下是示例结构:

def __exit__(self, exc_type, exc_val, exc_tb):
    # Close the connection and other logic applicable
    self.connection.close()

检查:Explaining Python's 'enter' and 'exit'了解详情。