Implementing use of 'with object() as f' in custom class in python
Those methods are pretty much all you need for making the object work with with
statement.
In __enter__
you have to return the file object after opening it and setting it up.
In __exit__
you have to close the file object. The code for writing to it will be in the with
statement body.
class Meter(): def __init__(self, dev): self.dev = dev def __enter__(self): #ttysetattr etc goes here before opening and returning the file object self.fd = open(self.dev, MODE) return self.fd def __exit__(self, type, value, traceback): #Exception handling here close(self.fd)meter = Meter('dev/tty0')with meter as m: #here you work with the file object. m.read()
Easiest may be to use standard Python library module contextlib:
import contextlib@contextlib.contextmanagerdef themeter(name): theobj = Meter(name) yield theobj theobj.close() # or whatever you need to do at exit
This doesn't make Meter
itself a context manager (and therefore is non-invasive to that class), but rather "decorates" it (not in the sense of Python's "decorator syntax", but rather almost, but not quite, in the sense of the decorator design pattern;-) with a factory function themeter
which is a context manager (which the contextlib.contextmanager
decorator builds from the "single-yield
" generator function you write) -- this makes it so much easier to separate the entering and exiting condition, avoids nesting, &c.
The first Google hit (for me) explains it simply enough:
http://effbot.org/zone/python-with-statement.htm
and the PEP explains it more precisely (but also more verbosely):