2016-09-22 58 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「:你願意解釋一下原因嗎? –