Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use contextmanagers for instance variables

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?

like image 854
P3trus Avatar asked Jan 06 '13 15:01

P3trus


People also ask

When would you use a context manager?

A context manager usually takes care of setting up some resource, e.g. opening a connection, and automatically handles the clean up when we are done with it. Probably, the most common use case is opening a file. The code above will open the file and will keep it open until we are out of the with statement.

Can context managers be used outside the with statement?

Yes, the context manager will be available outside the with statement and that is not implementation or version dependent. with statements do not create a new execution scope.

What does __ enter __ do in Python?

__enter__() is provided which returns self while object. __exit__() is an abstract method which by default returns None . See also the definition of Context Manager Types. New in version 3.6.


1 Answers

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.

like image 97
Ned Batchelder Avatar answered Oct 12 '22 23:10

Ned Batchelder