John Salerno wrote: >> Not sure about the with-- I just went to read the PEP on it, and it >> confused me greatly. :-) So, I don't know. > > Ditto. :)
No need to be confused; the "with" statement is actually very simple. Consider this piece of code: set things up try: do something finally: tear things down If you do this a lot, it would quite convenient if you could put the "set things up" and "tear things down" code in a library function, so you could reuse it. You can of course do something like def controlled_execution(callback): set things up try: callback(thing) finally: tear things down def my_function(thing): do something controlled_execution(my_function) but that's a bit verbose, especially if you need to modify local variables. Another approach is to use a one-shot generator, and abuse the for-in statement: def controlled_execution(): set things up try: yield thing finally: tear things down for thing in controlled_execution(): do something with thing but this looks a bit weird, and doesn't even work in 2.4 and earlier. So after contemplating a number of alternatives, GvR finally came up with a generalization of the latter, using an object instead of a generator to control the behaviour of an external piece of code: class controlled_execution: def __enter__(self): set things up return thing def __exit__(self, type, value, traceback): tear things down with controlled_execution() as variable: some code When the "with" statement is executed, Python evaluates the expression, calls the __enter__ method on the resulting value (which is called a "context guard"), and assigns whatever __enter__ returns to the given variable. Python will then execute the code body, and *no matter what happens in that code*, call the guard object's __exit__ method. For extra bonus, the __exit__ method can look at the exception, if any, and suppress or modify it, if necessary. For example, the following __exit__ method swallows any TypeError, but lets all other exceptions through: def __exit__(self, type, value, traceback): return isinstance(value, TypeError) In Python 2.5, the file object has been equipped with __enter__ and __exit__ methods; the former simply returns the file object itself, and the latter closes the file: >>> f = open("x.txt") >>> f <open file 'x.txt', mode 'r' at 0x00AE82F0> >>> f.__enter__() <open file 'x.txt', mode 'r' at 0x00AE82F0> >>> f.read(1) 'X' >>> f.__exit__(None, None, None) >>> f.read(1) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: I/O operation on closed file This wasn't very difficult, was it? </F> -- http://mail.python.org/mailman/listinfo/python-list