Reputation: 7235
How would I use a Contextmanager for instance variables? E.g.
Let's assume I've got some Connection
class, that must be closed on destruction. If I were to implement it as a ContextManager I could do.
with Connection() as c:
c.write('FOO')
c.ask('BAR?')
and it would get automatically closed on destruction. But what if I wanted to use it in a __init__
of another class, e.g. like the following example?
class Device(object):
def __init__(self):
self.connection = Connection() # Must be closed on destruction.
I dont want it to be closed on exit of the constructor, it should die when the object get's destroyed. I could use __del__
but this has it's downsides. Being used to RAII in C++ it baffles me.
So what is the best way to do it in this case?
Upvotes: 10
Views: 662
Reputation: 6744
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)
Upvotes: 2
Reputation: 375604
You should invoke self.connection.close
in your Device.close()
method, and then arrange for that to be invoked properly in your program, perhaps with a context manager.
__del__
is never worth it.
Upvotes: 6