2013-01-06 8 views
8

Wie würde ich einen Contextmanager für Instanzvariablen verwenden? Z.B. Nehmen wir an, ich habe eine Connection Klasse, die bei Zerstörung geschlossen werden muss. Wenn ich es als ContextManager implementieren würde, könnte ich es tun.Verwendung von Contextmanagern für Instanzvariablen

with Connection() as c: 
    c.write('FOO') 
    c.ask('BAR?') 

und es würde automatisch auf Zerstörung geschlossen werden. Aber was, wenn ich es in einer __init__ einer anderen Klasse, z. wie das folgende Beispiel?

class Device(object): 
    def __init__(self): 
     self.connection = Connection() # Must be closed on destruction. 

Ich möchte nicht, dass es beim Beenden des Konstruktors geschlossen wird, es sollte sterben, wenn das Objekt zerstört wird. Ich könnte __del__ verwenden, aber das hat seine Schattenseiten. Wenn ich an RAII in C++ gewöhnt bin, verblüfft es mich.

Also, was ist der beste Weg, um es in diesem Fall zu tun?

+2

Objektzerstörung Zeit ist nie die richtige Zeit für etwas, insbesondere nicht für die Ressourcenverwaltung. Vergessen Sie, dass es so etwas wie Müllsammlung gibt und dass alle Objekte auf unbestimmte Zeit leben. – delnan

Antwort

6

Sie sollten self.connection.close in Ihrer Device.close() Methode aufrufen und dann veranlassen, dass das in Ihrem Programm richtig aufgerufen wird, vielleicht mit einem Kontextmanager.

__del__ ist es nie wert.

1
from contextlib import contextmanager 

@contextmanager 
def connection(): 
    conn = Conn() 
    try: 
     yield conn 
    finally: 
     conn.close() 

class Conn(object): 
    def close(self): 
     print('Closing') 

class Device(object): 
    def __init__(self, conn): 
     self.conn = Conn() 

with connection() as conn: 
    d = Device(conn) 
Verwandte Themen