"from module import data; print(data)" vs "import module; print(module.data)"
steve+comp.lang.python at pearwood.info
Wed Feb 24 22:39:12 EST 2016
On Thursday 25 February 2016 12:07, Dan Stromberg wrote:
> Could people please compare and contrast the two ways of doing imports
> in the Subject line?
from module import data; print(data)
import module; print(module.data)
> I've long favored the latter, but I'm working in a code base that
> prefers the former.
> Is it fair to say that the former increases the surface area of your
> shared (sometimes mutable) state?
No, I can't say that it is. If anything, the opposite is the case: it
decreases the surface area, because `data` now is local to the importing
(not imported) module. Rebinding data will not affect anything else.
There are two scenarios (`from module import...` versus `import ...`), each
with two cases: mutation, and rebinding:
(1) from module import data
(a) Mutation (only applies to mutable data like lists, dicts etc)
In place mutation affects everything relying on module.data regardless of
how or where it is accessed.
(b) Rebinding (e.g. `data = `)
Because data is now a local name, you only affect the local scope.
(2) import module
(a) Mutation is no different from (1)(a) above. No change.
(b) Rebinding `module.data = ` affects the imported module, and therefore
everything that relies on it.
So the `from module import data` scenario reduces the number of ways that
you can affect other modules. That may be important to you, but usually the
answer to that is "well don't rebind attributes of modules unless you really
mean to". Sometimes doing `module.data = ...` is not a bad thing.
On the other hand, seeing something like:
should stand out to a reasonably experienced developer as possibly effecting
other modules. But:
may fool them into thinking that the change is only local to the current
module. Dangerous things should look dangerous: this is a point in favour of
using `import module` in preference to `from`.
> It's clear that the former saves keystrokes.
Code is read about 100 times more than it is written. Saving keystokes
should be quite low on the list of priorities.
It also saves line width, which may sometimes impact readability. But then
readability is only weakly correlated to line length. As you say:
> I find the latter a little more clear, because you don't have to go
> look for where a symbol came from.
which is also a very good point.
Personally, I prefer the `import module` over `from module` except when I
don't. Consequently I will sometimes even use both in the same module:
from itertools import zip_longest
depending on what's more convenient and useful for each.
I think that having a hard rule that you MUST use one or the other is silly,
but I guess that since Python makes "brace wars" irrelevant people need to
find something else to argue about.
> PS: Haskell seems better at the former than Python; Haskell tells you
> if you import two identical symbols from two different places, when
> you try to use one of them - not at import time. I believe in Python,
> whichever symbol you import last, wins. Haskell does not warn you at
> import time, which is fine. Not sure about OCaml or whatever else.
Haskell assumes that importing the same style from two places is an error
that needs warning about. I don't think it is, any more than:
s = 'foo'
s = 'bar'
is necessarily an error (particular if the two rebindings are separated by
code that does things). Both `import` and `from ... import` are rebinding
operations, like = assignment.
More information about the Python-list