71

Should I use

from foo import bar

OR

import foo.bar as bar

when importing a module and and there is no need/wish for changing the name (bar)?

Are there any differences? Does it matter?

Bach
  • 6,145
  • 7
  • 36
  • 61
embert
  • 7,336
  • 10
  • 49
  • 78
  • Try to avoid `as` wherever possible. – Vishvajit Pathak Jun 13 '20 at 09:58
  • 13
    Why? It looks redundant here, but itt's pretty common in the Python world to need to import something with the same name as something else. Even where it's not necessary, there are common stylistic reasons, such as `import pandas as pd`, `import numpy as np` that are pretty standard when working with those projects - that's the code I see everywhere and that's the suggested import in the documentation. I don't really see an issue with using `as`, it can often make code easier to read. – Tom Carrick Jun 13 '20 at 10:14

6 Answers6

56

Assuming that bar is a module or package in foo, there is no difference*, it doesn't matter. The two statements have exactly the same result:

>>> import os.path as path
>>> path
<module 'posixpath' from '/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/posixpath.pyc'>
>>> from os import path
>>> path
<module 'posixpath' from '/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/posixpath.pyc'>

If bar is not a module or package, the second form will not work; a traceback is thrown instead:

>>> import os.walk as walk
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named walk

* In Python 3.6 and before, there was a bug with the initialization ordering of packages containing other modules, where in the loading stage of the package using import contained.module.something as alias in a submodule would fail where from contained.module import something as alias would not. See Imports in __init__.py and `import as` statement for a very illustrative example of that problem, as well as Python issues #23203 and #30024.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 2
    hi @Martijn Pieters :), is there any reason ever why one would use the `import os.path as path` style? not this example in particular.. I mean I've searched through some biggest projects on github, CPython, Django, etc... absolute imports of type `import x` are done plain, with 1 word only ever, not forcing an alias by doing `import x.y.z as my_z`. I mean the import is useless without an alias; if you do `import x.y.z` it imports just `x` and binds it within the current namespace, in order to use `z` you would have to do `x.y.z` all the time, everytime – Marius Mucenicu Apr 15 '18 at 09:48
  • @George: Most developers would use `from x.y import z`, the syntax used in the question is not common. – Martijn Pieters Apr 15 '18 at 11:14
  • right, my thoughts exactly... I follow the convention of Google to import only packages and modules (as PEP8 does not enforce this, but wherever PEP8 is not complete, I enforce it with Google in favor of any other big projects such as Reddit, OpenStack, etc... simply because Google is... well.. Google :) and upon importing packages and modules I use what you said above.. either `import x` as just a plain `module/package` and access attrs thorugh `x` (self-explanatory in big modules) and wherever I have to go more than 1 level deep I use `from x.y import z`; thx for the reply:) – Marius Mucenicu Apr 15 '18 at 11:26
  • Yes I saw that. It would be nice to add the question of the python version to the answer! – beesleep May 30 '20 at 15:57
  • @beesleep: I added a footnote on that. – Martijn Pieters Jun 02 '20 at 11:21
30

This is a late answer, arising from what is the difference between 'import a.b as b' and 'from a import b' in python

This question has been flagged as a duplicate, but there is an important difference between the two mechanisms that has not been addressed by others.

from foo import bar imports any object called bar from namespace foo into the current namespace.

import foo.bar as bar imports an importable object (package/module/namespace) called foo.bar and gives it the alias bar.

What's the difference?

Take a directory (package) called foo which has an __init__.py containing:

# foo.__init__.py
class myclass:
    def __init__(self, var):
        self.__var = var

    def __str__(self):
        return str(self.__var)

bar = myclass(42)

Meanwhile, there is also a module in foo called bar.py.

from foo import bar
print(bar)

Gives:

42

Whereas:

import  foo.bar as bar
print(bar)

Gives:

<module 'foo.bar' from '/Users//..../foo/bar.py'>

So it can be seen that import foo.bar as bar is safer.

cdarke
  • 42,728
  • 8
  • 80
  • 84
  • 5
    I disagree with this. The `__init__.py` file is the module's interface to the outside world. If the `__init__` file causes the import to be changed, that may well be what the author intended. It's safer to use the standard way to import modules. PEP8 recommends the `from x import y` style. https://www.python.org/dev/peps/pep-0008/#imports – Rich Smith May 27 '20 at 11:05
  • 4
    The question was, is there a difference? There is, and one can have unexpected side effects. – cdarke Jun 18 '20 at 18:30
  • 7
    I was disagreeing with the comment that `import ... as` was safer, not the rest of your answer. It can have "side effects", but they could be intended by the author of the module. Bypassing the intended interface to the module is breaking an abstraction and asking for trouble. – Rich Smith Jun 19 '20 at 11:27
  • 1
    **`from foo import bar` seems much "safer"**, judging by the presented evidence. – Mateen Ulhaq Mar 08 '21 at 01:16
21

Both are technically different:

  • import torch.nn as nn will only import a module/package torch.nn, wheres
  • from torch import nn can and will prefer to import an attribute .nn from the torch module/package. Importing a module/package torch.nn is a fall.back.

In practice, it is bad style to have the same fully qualified name refer to two separate things. As such, torch.nn should only refer to a module/package. In this common case, both import statements are functionally equivalent: The same object is imported and bound to the same name.

Which one to choose comes down to preference if the target always is a module. There are practical differences when refactoring:

  • import torch.nn as nn guarantees .nn is a module/package. It protects against accidentally shadowing with an attribute.
  • from torch import nn does not care what .nn is. It allows to transparently change the implementation.

7.11. The import statement

The basic import statement (no from clause) is executed in two steps:

  1. find a module, loading and initializing it if necessary
  2. define a name or names in the local namespace for the scope where the import statement occurs.

[...]

The from form uses a slightly more complex process:

  1. find the module specified in the from clause, loading and initializing it if necessary;

  2. for each of the identifiers specified in the import clauses:

    1. check if the imported module has an attribute by that name
    2. if not, attempt to import a submodule with that name and then check the imported module again for that attribute
YaOzI
  • 16,128
  • 9
  • 76
  • 72
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
17

You can use as to rename modules suppose you have two apps that have views and you want to import them

from app1 import views as views1
from app2 import views as views2

if you want multiple import use comma separation

>>> from datetime import date as d, time as t
>>> d
<type 'datetime.date'>
>>> t
<type 'datetime.time'>
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
A.Zaben
  • 675
  • 6
  • 10
11

The only thing I can see for the second option is that you will need as many lines as things you want to import. For example :

import foo.bar as bar
import foo.tar as tar
import foo.zar as zar

Instead of simply doing :

from foo import bar, tar, zar
Depado
  • 4,811
  • 3
  • 41
  • 63
  • PEP8 recommends putting imports on separate lines: https://www.python.org/dev/peps/pep-0008/#imports . – Rich Smith May 27 '20 at 11:10
  • @RichSmith regarding your link, it actually says it's correct to import multiple things from the same package in a single line (the "it is okay to say this though" part). – Depado May 28 '20 at 16:20
  • I've always interpreted that line as PEP8 saying it was OK to import classes and constants etc. from a single module on one line (`subprocess` being a module). It could be interpreted as "this style is OK", but above it says `Imports should usually be on separate lines`. It could be clearer. – Rich Smith May 29 '20 at 13:11
  • I've asked this as a question: https://stackoverflow.com/questions/62087225/what-is-the-pep8-recommendation-for-multiple-imports-from-a-package – Rich Smith May 29 '20 at 13:50
2

The difference between import module and from module import is mainly subjective. Pick the one you like best and be consistent in your use of it. Here are some advantage of both to help you decide.

advantage of import

  1. Less maintenance of your import statements.
  2. Don't need to add any additional imports to start using another item from the module

advantage of from torch import nn

  1. Less typing to use the nn
  2. More control over which items of a module can be accessed
Prathamesh
  • 1,064
  • 1
  • 6
  • 16