2

I’m working on some code that should run under both Python 2.7.x and Python 3.3+ unchanged, and uses Unicode data text file I/O.

So which is better—and why?

Variant 1:

import io
encoding = 'utf-8'

with io.open('Unicode.txt', 'w', encoding=encoding) as f:
    …
with io.open('Unicode.txt', 'r', encoding=encoding) as f:
    …

Variant 2:

from io import open
encoding = 'utf-8'

with open('Unicode.txt', 'w', encoding=encoding) as f:
    …
with open('Unicode.txt', 'r', encoding=encoding) as f:
    …

Personally, I’d tend to use Variant 2, because the code should be as Python-3-ish as possible, just providing backport stubs for Python 2.7.x. It also looks cleaner and I wouldn’t have to change existing code much. Also I think maybe I could save a little by not importing the whole io module.

Moonbase
  • 75
  • 1
  • 1
  • 12
  • 2
    You always import a whole module. The only difference this makes is what name is bound in your current module globals (so either `io` is bound, or `open` is bound). – Martijn Pieters Nov 25 '16 at 17:23
  • Didn’t know that, thanks for the explanation, Martijn! – Moonbase Nov 25 '16 at 17:35
  • 5
    @MartijnPieters this is not a duplicate of the other question. It's specific to 'open'. Using Variant 2 means that you can just delete the whole import line once Python 3 has been fully adopted. – Emil Dec 05 '17 at 20:43
  • Voting to reopen because the duplicate is about general importing style, while this question was really about future-proofing the `open()` function. – joanis Jul 19 '22 at 16:35

1 Answers1

0

As @smido has pointed out in a comment, open is a built-in in both Python 2 and 3, then it is already available in both versions of Python without any imports.

Now, assuming that you are asking about what is a better way to import a package, i.e., import module vs from module import ..., formally there is no better way, it is up to you, but I think it is good to use variant 1 since in case you will use another module that has a function called open(), the last import will override the former.

You are right that in general in Python 3 is very common to use from module import field, but I personally would use the first variant. In the end, if you are worried about typing more, a good editor or IDE would help you. :-)

lmiguelvargasf
  • 63,191
  • 45
  • 217
  • 228
  • `open` is a built-in in both python 2 and python 3, so you already have the open imported on both pythons. the import `from io import open` will only change what's used in python2. This is against the argument that 'you shouldn't do this because you might want to use some other `open` from other module' – smido Jun 25 '19 at 08:35
  • @smido, thanks for the observation. I have updated my answer. – lmiguelvargasf Jun 26 '19 at 04:07
  • This answer is missing the whole point of the question. The question was not at all about the best import style. It was specifically about future-proofing the code. And OP's variant 2 in the option that would best future-proof the code. – joanis Jul 19 '22 at 16:32
  • The key point of this question is that Python 2's default `open()` function does not support utf-8, whereas Python 3's does, and so does `io.open`. Adding the line `from io import open` makes code look the same in Python 2 and Python 3 from that point on in the file. – joanis Jul 19 '22 at 16:34