What's the difference between from foo import bar
and import foo.bar as bar
?
Is there any difference as far as Python namespaces and scope are concerned? If you want to use something from bar
(say a function called whatever
), you'd call it as bar.whatever()
using either approach.
I see both styles of imports in a code base I'm working with and was wondering what differences they entail, if any, and what would be considered the more "Pythonic" approach.
There is a difference, both for when there is a bar
module or package inside the foo
package, and if bar
is not a module at all.
Considered the following foo
package:
foo/
__init__.py
bar.py
If the __init__.py
file defines a global name bar
too, then the first example will import that object. The second example will import the bar.py
module.
However, once the foo.bar
module has been imported, the Python import machinery will set the name bar
in the foo
package, replacing any pre-existing bar
global in __init__.py
:
$ ls -1 foo/
__init__.py
bar.py
$ cat foo/__init__.py
bar = 'from the foo package'
$ cat foo/bar.py
baz = 'from the foo.bar module'
$ python
Python 2.7.12 (default, Aug 3 2016, 18:12:10)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from foo import bar
>>> bar
'from the foo package'
>>> import foo.bar as bar
>>> bar
<module 'foo.bar' from 'foo/bar.pyc'>
>>> bar.baz
'from the foo.bar module'
>>> from foo import bar
>>> bar
<module 'foo.bar' from 'foo/bar.pyc'>
The other case is where there is no bar.py
submodule. foo
could either be a package, or a simple module. In that case from foo import bar
will always look for an object in the foo
module, and import foo.bar as bar
will always fail:
$ cat foo.py
bar = 'from the foo module'
$ python
Python 2.7.12 (default, Aug 3 2016, 18:12:10)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo
>>> foo.bar
'from the foo module'
>>> from foo import bar
>>> bar
'from the foo module'
>>> import foo.bar as bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named bar
Note that in all cases where the import succeeds, you end up with a global name bar
bound to something, either an object from a module, or a module object.
When bar is not a module, there is a huge difference:
# foo.py
bar = object()
Here from foo import bar
would be normal in python, but import foo.bar as bar
would raise an ImportError: No module named bar
.
Usually we only use the "as" construct to alias a name: either for adding some context to the name to improve readability, or to avoid a clash with another name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With