2016-09-22 2 views
1

Ich möchte eine Klasse haben, die einen IMAP-Verbindung und verwenden Sie es mit einer with Aussage darstellt, wie folgt:Schließen einer Verbindung mit einer `with` Aussage

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) 

Natürlich scheitert dies seit IMAPConnectionsclose kein Attribut hat. Wie kann ich die Verbindung speichern und an die __exit__-Funktion übergeben, wenn die with-Anweisung abgeschlossen ist?

Antwort

3

Sie müssen die Verbindung in Objektattributen speichern. Etwas wie folgt aus:

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() 

Sie möchte auch list Methode für Sie Klasse implementieren.

Edit: Ich habe gerade jetzt erkannt, was Ihr eigentliches Problem ist. Wenn Sie tun with SomeClass(*args, **kwargs) as cc ist kein Wert von __enter__ Methode zurückgegeben. c ist eine Instanz von SomeClass. Das ist eine Wurzel Ihres Problems, dass Sie die Verbindung von __enter__ zurückgegeben und angenommen haben, dass c diese Verbindung ist.

+0

Ha, Gotcha. Danke! – mart1n

+0

Ich fügte einige weitere Erklärung in meine Antwort. Hoffe, es ist hilfreich –

0

Sie müssen eine __exit__() Funktion in Ihrer IMAPConnection Klasse implementieren.

__enter__() Funktion wird vor der Ausführung des Codes innerhalb des with Block genannt, wo als __exit__() genannt wird, während der Block with austritt.

Unten ist die Probenstruktur:

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

Check: Explaining Python's 'enter' and 'exit' für weitere Informationen.

+0

@Downvoter ": Möchten Sie den Grund erklären? –

Verwandte Themen