2016-09-22 28 views
1

我想有一个代表IMAP连接的一类,并用with语句中使用它,如下所示:关闭了连接`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有没有属性closewith声明完成后,如何存储连接并将它传递给__exit__函数?

回答

3

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

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 cc不是由__enter__方法返回的值。 cSomeClass的实例。这是您从__enter__返回连接的问题的根源,并且假定c表示连接。

+0

Ha,gotcha。谢谢! – mart1n

+0

我在答案中加了一些解释。希望它有用 –

0

您需要在IMAPConnection类中实现__exit__()函数。

__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'以获取更多信息。

+0

@Downvoter“:你愿意解释一下原因吗? –