urlopen, six, and py2
Matt Wheeler
m at funkyhat.org
Wed Mar 2 09:35:20 EST 2016
On 2 March 2016 at 14:05, Fabien <fabien.maussion at gmail.com> wrote:
> [snip]
> My question is: why does the python3 version need a "with" block while the
> python2 version doesn't? Can I skip the "with" entirely, or should I rather
> do the following:
It's not a case of "need", using the "with" construction is an added
feature, not a burden!
> from six.moves.urllib.request import urlopen
>
> try:
> with urlopen('http://www.google.com') as resp:
> _ = resp.read()
> except AttributeError:
> # python 2
> resp = urlopen('http://www.google.com')
> _ = resp.read()
This is poor practise as you aren't closing "resp".
This leaves state lying around that you don't need anymore, which is
the whole purpose of the context manager that 3 provides.
It will *usually* be cleaned up when leaving the current scope, but
won't if there is an exception thrown. Using the context manager
ensures resp is *always* cleaned up properly even if an exception is
thrown.
I agree that six should probably handle this, but in the meantime you
could use contextlib.closing ([1]) rather than rolling your own. It
even uses urlopen as an example.
If you absolutely want to roll your own then don't bother with the
context manager provided by 3 at all, just use:
resp = urlopen('http://www.google.com')
try:
_ = resp.read()
finally:
resp.close()
But as this is wordier and more fragile than using a context manager
to clean up for you, I expect you won't bother :).
[1] https://docs.python.org/2/library/contextlib.html#contextlib.closing
--
Matt Wheeler
http://funkyh.at
More information about the Python-list
mailing list