← Back to team overview

launchpad-dev team mailing list archive

Re: The with statement

 

On Wed, Jan 27, 2010 at 12:31:04PM -0500, Barry Warsaw wrote:
> Now that we're on Python 2.5, we have a few new language features at our
> disposal.  In today's AMEU reviewer meeting, I brought up the 'with' statement
> and was asked to write something up about it.  The with statement will be okay
> to use in Launchpad code, so you'll see more of it crop up, and it's good to
> know how and when to use it.
> 
> First off, in Python 2.5 you need a future import to enable the with
> statement.  'with' is a keyword in Python 2.6, so when we move to that version
> we can get rid of all the future imports:

Thanks for the write-up, Barry. I think the with statement is good, but
I'd like to re-iterate one of Jeroen's concern (at least part of it, I
think).


> For example, if you wanted to print every line in /etc/password, and you were
> anal like me, you'd do something like:
> 
> >>> fp = open('/etc/passwd')
> >>> try:
> ...     for line in fp:
> ...         sys.stdout.write(line)
> ... finally:
> ...     # Don't wait for gc to free the file descriptor.
> ...     fp.close()
> 
> Look at how much nicer this is using the with statement.  This works because
> built-in file objects already support the context manager protocol:
> 
> >>> with open('/etc/passwd') as fp:
> ...     for line in fp:
> ...         sys.stdout.write(line)

I think this is an excellent use of with. It's well-known that files
work like this, so it's easy to understand, and the code gets cleaner.


> It's also very easy to write your own context managers to work with the
> with-statement.  The documentation has all the gory details, but essentially,
> you just need to implement an __enter__() method and an __exit__() method.
> The former gets called when the with-statement starts, and the latter gets
> called when it's done.  The signature of __exit__() is a little tricky to
> allow it to handle exceptions in the body of the with-statement, but usually
> you don't care and will just let those percolate up.

 think we should be a bit careful using it for other things than files.
I'm sure there are good use cases for using with with custom
implementations, but we should be careful not to over-use it. Just
because it's easy to write, doesn't mean that we should do it. It's very
easy to get carried away, wanting to use new features just because. It's
important to think about the end result.

So, when writing context manager implementations, you (and the reviewer)
should ask youself the question: how easy is it to see what's going on
when the with statement is used? The with statement does add a level of
magic. If you need to chase down the implementation to figure out what's
going on, it's not a good design. As I see it, the with statement is
mainly useful wehre you have a well-known behaviour, where it's easy to
find out what's going on (for example from the name), or when the
clean-up step isn't important. This doesn't mean that we should avoid
writing our own context managers at all cost, just that we should
evaluate the benefit. The more an object is used in the code, the more
likely it is that the behaviour will be well-known.


-- 
Björn Tillenius | https://launchpad.net/~bjornt



Follow ups

References