'with' gets better with python 3.1
h3manth.com
h3manth.com
And if you're going to create a custom "composed" context manager every single time, you're probably better off just nesting `with` statements.
infile = open('site.log'); outfile = open('err.log', 'w')
for line in infile:
if 'ERROR' in line:
outfile.write(line)
infile.close(); outfile.close()
Sure, you're saving a line with the files being automatically closed at the end of your scope, but hardly "MIND == BLOWN".What am I missing?
Imagine you open 'infile', but then opening 'outfile' fails. To prevent a resource leak, now you need to close 'infile'. The linked code guarantees this. Likewise if there is any error which aborts the copying, both files will get closed and you don't have to worry so much about corner cases.
See this for more:
More... "philosophy" here: http://stackoverflow.com/questions/11373502/zen-of-python-vs...
That's actually pretty significant if you're, say, using Pypy or IronPython, otherwise you're leaking handlers if you've got an error raised.
But he was actually comparing the code to:
with open('site.log') as infile:
with open('err.log', 'w') as outfile:
# code
. MIND=BLOWN is tongue-in-cheek. Hopefully. Then again, he's commenting on a 2 or 3 years old version of python so...Ruby doesn't need "with" because "with" is really just a limited special case of what you can do with blocks.
The Python fans will counter that their less general solution is harder to abuse.
Not sure why anybody would say that, you can plenty abuse `with` if you want to have fun, the only thing you can't do is "dual-use" the block really (grab a context and invoke the block multiple times). And that you could always do with a decorator, if you're going there. The only thing `with` is is less flexible/general.
`unwind-protect` or `BlockClosure#ensure:` are probably much better examples of the philosophy opposite python though, I've always found ruby rather half-assed.
I haven't switched to Py3k yet either, but I'm just waiting for a few more packages I use heavily to get the bugs worked out.
$ python2.7
Python 2.7.3 (default, Apr 13 2012, 13:51:30)
>>> {i: i+1 for i in range(5)}
{0: 1, 1: 2, 2: 3, 3: 4, 4: 5}Those are actually fairly minor in the grand scheme of things (and compound `with` statements have been backported to 2.7).
More interesting are:
3.0
* unicode strings by default and much better overall support of unicode
* chained exceptions (I don't believe they've been backported)
3.2
* argparse merged to the stdlib
* ElementTree 1.3 finalized in stdlib (3.2)
* functools.lru_cache, itertools.accumulate (nothing game-changing, but nice to have in the stdlib)
* threading.Barrier
* concrete tzinfo implementation (for fixed UTC offsets)
* contextlib.ContextDecorator (creates a type which works both as a contextmanager and a function decorator), and improved contextmanager support across the board (ftplib, popen, TarFile, ...)
3.3 (soon to be released)
* Virtual environments shipped by default
* Namespace packages
* Kind-of obscure, but flexible string representations (strings can dynamically and transparently switch their implementation between latin-1, ucs-2 and ucs-4, this kills the narrow/wide compile-flag shit and generally makes strings more space-efficient)
* sub-generator delegation, instead of:
for item in sub_generator_function():
yield item
you can just write:
yield from sub_generator_function().
it also correctly forwards sent and thrown values (generator.send() and generator.throw()) to the sub-generator, so it actually translates into an unholy mess which now just works and allows more easily splitting a large function into sub-iterators.
* lzma/xz support (7z)I'm actually excited for 3.3, there's plenty of cool stuff in there.
[0] http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec...