On 2 March 2016 at 14:05, Fabien <fabien.mauss...@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 -- https://mail.python.org/mailman/listinfo/python-list