594

I've tried to find a comprehensive guide on whether it is best to use import module or from module import. I've just started with Python and I'm trying to start off with best practices in mind.

Basically, I was hoping if anyone could share their experiences, what preferences other developers have and what's the best way to avoid any gotchas down the road?

Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
Filip Dupanović
  • 32,650
  • 13
  • 84
  • 114
  • 19
    I just wanted to let you know, that the selected answer is wrong. It states that the difference is subjective whereas there is a difference. This could possibly lead to hard to detect bugs. See Michael Ray Lovetts answer. – Mayou36 Jul 27 '17 at 13:13
  • 1
    Related post - [Reasoning behind `from … import …` syntax in Python](https://stackoverflow.com/q/3600352/465053) & ['import module' vs. 'from module import function'](https://softwareengineering.stackexchange.com/q/187403/236257) – RBT Jul 23 '18 at 09:56
  • 5
    **There's a hell of a difference between importing specific named identifiers `'from module import X,Y,Z` vs `'from module import *`**. The latter pollutes your namespace and can give unpredictable results depending on what's going on in module. Worse still is doing `from module import *` with multiple modules. – smci Sep 15 '18 at 01:35
  • The Python Language does not have standart, but there is a nice book, which from Python 3.* is mostly as Python Reference written originally by Gvinno Van Rossum (author of the language): https://docs.python.org/3/tutorial/ – Konstantin Burlachenko Oct 17 '21 at 16:24
  • For sublte and complete description how import system is working you can read a dedicated section from https://docs.python.org/3/reference/index.html, specifically, it is: https://docs.python.org/3/reference/import.html – Konstantin Burlachenko Oct 17 '21 at 16:26
  • Another document: https://docs.python.org/3/reference/simple_stmts.html#the-import-statement describes various statements, and from that document there is a description for logic of work for `import` and `from` statements description. – Konstantin Burlachenko Oct 17 '21 at 16:31
  • This post gives some speed benchmarks between `import module` and from `module import x`: https://towardsdatascience.com/6-bad-manners-makes-your-python-program-slower-15b6fce62927 personally I could not reproduce them and it seems that the speed is the same. So probably the answer depends actually on ease of maintenance and name space potential issues as described by some answers – Iqigai Feb 01 '22 at 09:37
  • Obviously, the python import system is a nightmare, and the best advice for beginners is just "try stuff and see how it works - if it's confusing and frustrating, that's normal." In some cases there are meaningful differences in the way you import things, sometimes it's mostly just taste. Best bet: do it in the way that works, but try to have a reason for it – Nathan Chappell Mar 09 '23 at 07:51
  • @NathanChappell On the contrary: the python import system is powerful and the default configuration is elegant. There are very few specific things that need to be understood in order to use it properly, and they are easy to explain. The only actual problems are a) the Internet is full of people explaining them wrongly; b) people want it to work differently than how it actually does (for example, the way it works in Java, or in JavaScript). – Karl Knechtel Apr 28 '23 at 19:37
  • **people want it to work differently than how it actually does** – Nathan Chappell May 02 '23 at 06:34

23 Answers23

612

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

import module

  • Pros:
    • Less maintenance of your import statements. Don't need to add any additional imports to start using another item from the module
  • Cons:
    • Typing module.foo in your code can be tedious and redundant (tedium can be minimized by using import module as mo then typing mo.foo)

from module import foo

  • Pros:
    • Less typing to use foo
    • More control over which items of a module can be accessed
  • Cons:
    • To use a new item from the module you have to update your import statement
    • You lose context about foo. For example, it's less clear what ceil() does compared to math.ceil()

Either method is acceptable, but don't use from module import *.

For any reasonable large set of code, if you import * you will likely be cementing it into the module, unable to be removed. This is because it is difficult to determine what items used in the code are coming from 'module', making it easy to get to the point where you think you don't use the import any more but it's extremely difficult to be sure.

NullUserException
  • 83,810
  • 28
  • 209
  • 234
Mark Roddy
  • 27,122
  • 19
  • 67
  • 71
  • 111
    +1 for discouraging usage of "from module import *", it just clutters the namespace. – Christian Witts Apr 03 '09 at 06:49
  • 32
    cluttering the namespace is *not* the most problematic part of "import *", it's the reduction in readability: Any name conflicts will show themselves in (unit) testing. But all the names you use from the imported module will be bare, with nary a hint were they come from. I absolutely loathe "import *". – Jürgen A. Erhard Dec 26 '09 at 19:59
  • 37
    Doesn't the Zen of Python say explicit is better than implicit? – Antony Koch Feb 24 '11 at 11:51
  • 10
    `from module import *` can be particularly useful, if using it as: `if(windows):\n\t from module_win import * \n else: \n\t from module_lin import *`. Then your parent module can potentially contain OS independent function names, if the function names in module_lin & module_win have same names. It's like conditionally inheriting either class. – anishsane Oct 29 '13 at 14:57
  • 7
    -1: The difference is not mainly subjective. It actually changes semantics in some cases. (That's a fact, though I have no idea why it works this way.) See this answer for an example: http://stackoverflow.com/a/20863145/1143274 – Evgeni Sergeev Aug 06 '14 at 06:39
  • 28
    @anishsane. There is another way do it. import module_win as something. Then always use something.method_name() – Vinay Nov 11 '15 at 14:38
  • 3
    One semantic difference is that for immutable objects, `from mod import foo` creates a new `foo`, whereas `import mod; mod.foo` uses the same `foo` object as the one in `mod`. But `foo` should probably be hidden behind accessors anyway. – jpkotta May 18 '16 at 19:28
  • 7
    Another pro for `from module import foo`: to **announce a weak dependency**. When you need a module that's not in the standard library just for one tiny foo in it, this shows for posterity that the dependency could be removed by refactoring the use of foo. – Bob Stein Jun 05 '16 at 16:21
  • How about importing `*` when working with a framework rather than a module? Like, every code using tkinter starts with `from tkinter import *`, would you consider it bad practice and recommend `import tkinter` instead? – Right leg Dec 09 '16 at 06:45
  • import * is overused. But that doesn't mean it should never be used. It's a particularly useful shortcut when using small modules for projects that do not need to scale up that much. For example I like `from turtle import *` – Samie Bencherif Dec 26 '16 at 19:40
  • 3
    @Rightleg I've seen `import tkinter as tk`, maybe that answers your question? – Mark Ransom Feb 10 '17 at 20:51
  • @MarkRansom Hm, not really. While I know `import as` and don't really see any downside to it, I'm rather wondering how bad it would be to `import *` when working with a single big library. – Right leg Feb 11 '17 at 04:23
  • @EvgeniSergeev Your link does not demonstrate a difference in semantics between the import styles. It only shows that `import Image` is different from `from PIL import Image`. This has nothing to do with import style, it's a difference in the actual module structure. `from PIL import Image; Image` and `import PIL; PIL.Image` are equivalent; `import Image` is totally different. – Carl Meyer May 17 '17 at 16:18
  • One non-stylistic difference between the two styles that should be mentioned in this answer is that `from module import Thing` can cause circular-import ImportError (because it requires `module` to be fully executed right away) whereas `import module` would work without error in the same situation (as long as `module.Thing` is only accessed inside a function, not in import-time code). – Carl Meyer May 17 '17 at 16:20
  • 2
    Does it make any difference in a size of a module being imported? When I compile my souce file, is it the same to import one or the other way if I want to keep it smaller? – Hrvoje T Jul 13 '17 at 06:43
  • 5
    -1 This answer is wrong. There is a difference. See @Michael Ray Lovetts answer for the true answer. There is a **crucial** difference! – Mayou36 Jul 27 '17 at 13:11
  • @Rightleg As you may have noticed I try to encourage the use of `import tkinter as tk` in most of my Tkinter answers. I strongly agree with Jürgen A. Erhard that the main issue with star imports is that they impact readability, since it means you have no easy way of seeing which names are local and which are imports. (And of course code that does multiple star imports is far worse on that score, plus you have the potential for name collision). I admit it's not so bad in Tkinter since you're mostly importing widget names, in Uppercase, which makes them stand out from local lowercase names. – PM 2Ring Oct 12 '17 at 09:13
  • @Rightleg (cont) However, a Tkinter star import does dump a *lot* of stuff into your namespace - 136 names in Python 3, and 175 names in Python 2! OTOH, trying to do stuff in `ctypes` _without_ a star import is madness. :) – PM 2Ring Oct 12 '17 at 09:16
  • I sometimes run into something like `import module.api as mod`. If I drop `.api`, it won't work. Is this a module-specific issue. If not, is there any broader explanation that applies to all python modules? – steven Feb 19 '19 at 02:34
  • `from x.y import z from x.y.z import foo temp = z.SomeEnum.red ` foo is the function. SomeEnum is a Enum Is it ok to have import both the module and also a function in the same file? – Prabu Raj Aug 11 '20 at 06:31
  • It's extremely easy to determine what function are being used from a star import. I made a function to use pylint to do it for me, by scanning for every `W0614: Unused import` error and then subtracting those functions from the set of all functions imported from the module. What remains, is what needs to be imported. Works perfectly. – SurpriseDog Apr 14 '21 at 22:30
  • What's the difference between `from module import foo` and `from module import *`? (excuse me, I am relatively new to python) – Mailbox Apr 23 '23 at 17:17
279

There's another detail here, not mentioned, related to writing to a module. Granted this may not be very common, but I've needed it from time to time.

Due to the way references and name binding works in Python, if you want to update some symbol in a module, say foo.bar, from outside that module, and have other importing code "see" that change, you have to import foo a certain way. For example:

module foo:

bar = "apples"

module a:

import foo
foo.bar = "oranges"   # update bar inside foo module object

module b:

import foo           
print foo.bar        # if executed after a's "foo.bar" assignment, will print "oranges"

However, if you import symbol names instead of module names, this will not work.

For example, if I do this in module a:

from foo import bar
bar = "oranges"

No code outside of a will see bar as "oranges" because my setting of bar merely affected the name "bar" inside module a, it did not "reach into" the foo module object and update its bar.

martineau
  • 119,623
  • 25
  • 170
  • 301
Michael Ray Lovett
  • 6,668
  • 7
  • 27
  • 36
  • With that last example, can you still call 'foo.bar = "orange"' to update 'bar' inside 'foo'? – velocirabbit May 03 '15 at 21:42
  • 4
    No, in the last example, the name 'foo' is unknown – Ghislain Leveque Jan 11 '16 at 13:59
  • 78
    THIS answer provides the "true" answer on the question: what is the difference between the two import variants – Mayou36 Jul 23 '17 at 09:24
  • 5
    Wrote some snippet to prove this answer is absolutely right, but what's the rationale behind this? – huangbeidu Mar 26 '18 at 09:39
  • I think what you are saying is import symbol names to have local variables but import module names to have global variables??? – WinEunuuchs2Unix Dec 17 '18 at 02:15
  • Hi Micheal, just wondering, do you know or have some reference explaining why this is the case? If we test variables imported either using `import m` or `from m import var` (`m.var is var` prints True) we can see that they are exactly the same variable so it seems at least they both should change values regardless of importation method. By the way, this answer should be the accepted one IMO. – Willian Fuks Mar 05 '21 at 01:40
  • 4
    This is not entirely true. The case illustrated is a result of strings being immutable. If instead "bar" was a list, then having say "foo.bar.append('oranges')" in module a, would be reflected when printing the list in module b. – rohit_r May 14 '21 at 13:08
  • 2
    @gateway2745 exactly. This is merely an example of shadowing. Functions requiring `global` have the same issue. – Jeppe Jun 07 '21 at 09:46
  • 2
    Although I agree with the technicality of this answer, I would like to point out that this is a bad practice. You should avoid changing global variables *as much as possible* to avoid very difficult to find bugs. Multiple modules changing a global variable exponentially increases this risk. Please never do this. – Chris Collett Jun 14 '21 at 18:35
  • 2
    This is hugely important. Also @ChrisCollett The answer is helpful because without knowing that one changes the module globally, you might be changing the module globally without knowing it. So the answer helped me to stop changing the module globally where it already was. – scorgn Aug 03 '21 at 18:13
  • 2
    @rohit_r I think it's not related to the immutability of the object. If you did `bar = [1,2,3]` that would also not be reflected in module b or foo. It's really because the `bar` imported by `from foo import bar` is really a new reference to the object in module foo, and the assignment overwrites the local reference only while keeping the one in module foo untouched. – mxt3 May 10 '22 at 08:12
  • This is a bad answer, and is one of the reasons that using global variables is usually a bad idea. When importing "from module import thing", a copy of "thing" is created in the current namespace. When importing the module, we reference "thing" as "module.thing", and if we modify or replace it with a different value, that will affect all references to "module.thing". Modifying global variables in one module from another module has a bad code smell and is prone to bugs. – Steve Daulton Jul 25 '23 at 20:13
120

Even though many people already explained about import vs import from, I want to try to explain a bit more about what happens under the hood, and where all the places it changes are.


import foo:

Imports foo, and creates a reference to that module in the current namespace. Then you need to define completed module path to access a particular attribute or method from inside the module.

E.g. foo.bar but not bar

from foo import bar:

Imports foo, and creates references to all the members listed (bar). Does not set the variable foo.

E.g. bar but not baz or foo.baz

from foo import *:

Imports foo, and creates references to all public objects defined by that module in the current namespace (everything listed in __all__ if __all__ exists, otherwise everything that doesn't start with _). Does not set the variable foo.

E.g. bar and baz but not _qux or foo._qux.


Now let’s see when we do import X.Y:

>>> import sys
>>> import os.path

Check sys.modules with name os and os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

Check globals() and locals() namespace dicts with os and os.path:

>>> globals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> locals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> globals()['os.path']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os.path'
>>>

From the above example we found that only os is inserted in the local and global namespace. So, we should be able to use:

>>> os
<module 'os' from
  '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> os.path
<module 'posixpath' from
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>

But not path.

>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

Once you delete the os from locals() namespace, you won't be able to access os as well as os.path even though they exist in sys.modules:

>>> del locals()['os']
>>> os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

Now let's talk about import from:

from:

>>> import sys
>>> from os import path

Check sys.modules with os and os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

We found that in sys.modules we found as same as we did before by using import name

OK, let's check how it looks like in locals() and globals() namespace dicts:

>>> globals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> locals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['os']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os'
>>>

You can access by using name path not by os.path:

>>> path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

Let's delete 'path' from locals():

>>> del locals()['path']
>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

One final example using an alias:

>>> from os import path as HELL_BOY
>>> locals()['HELL_BOY']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['HELL_BOY']
<module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>

And no path defined:

>>> globals()['path']
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
James Sapam
  • 16,036
  • 12
  • 50
  • 73
  • 16
    While this is verbose, this is really the best answer in the list for a fairly complex question. It provides actual code to help explain the "under the hood" subtleties, which are more important than style, for this particular issue. I wish I could upvote it more than once! – Mike Williamson Dec 09 '15 at 18:21
  • 1
    Does using `as SYMBOL` change how this answer works at all? – Maximilian Burszley Jan 29 '20 at 18:20
44

Both ways are supported for a reason: there are times when one is more appropriate than the other.

  • import module: nice when you are using many bits from the module. drawback is that you'll need to qualify each reference with the module name.

  • from module import ...: nice that imported items are usable directly without module name prefix. The drawback is that you must list each thing you use, and that it's not clear in code where something came from.

Which to use depends on which makes the code clear and readable, and has more than a little to do with personal preference. I lean toward import module generally because in the code it's very clear where an object or function came from. I use from module import ... when I'm using some object/function a lot in the code.

dr_
  • 2,400
  • 1
  • 25
  • 39
dwc
  • 24,196
  • 7
  • 44
  • 55
  • 1
    Is there a way to use `from M import X` and still get the benefit of using the qualifiers somehow? It seems you could get the best of both worlds if you could still do `M.X`after that import. – arthropod Sep 05 '18 at 03:35
  • @artgropod: Kinda. You can do `class m: from something.too.long import x, y, z`. Wouldn't really recommend that though. – Lie Ryan Jan 11 '19 at 01:22
35

I personally always use

from package.subpackage.subsubpackage import module

and then access everything as

module.function
module.modulevar

etc. The reason is that at the same time you have short invocation, and you clearly define the module namespace of each routine, something that is very useful if you have to search for usage of a given module in your source.

Needless to say, do not use the import *, because it pollutes your namespace and it does not tell you where a given function comes from (from which module)

Of course, you can run in trouble if you have the same module name for two different modules in two different packages, like

from package1.subpackage import module
from package2.subpackage import module

in this case, of course you run into troubles, but then there's a strong hint that your package layout is flawed, and you have to rethink it.

Stefano Borini
  • 138,652
  • 96
  • 297
  • 431
  • 11
    In the last case, you can always use: import pkgN.sub.module as modN giving you distinct names for each module. You can also use the 'import modulename as mod1' pattern to shorten a long name, or to switch between implementations of the same API (e.g. DB API modules) with a single name change. – Jeff Shannon Apr 03 '09 at 00:59
  • When you use `pathlib`, do you always write it out as `pathlib.Path` ? – run_the_race Apr 25 '22 at 17:18
16
import module

Is best when you will use many functions from the module.

from module import function

Is best when you want to avoid polluting the global namespace with all the functions and types from a module when you only need function.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
  • 14
    Surely the only thing in the global namespace if you do 'import module' is 'module' ? You only pollute the namespace if you do 'from .. import *'. – John Fouhy Apr 02 '09 at 23:25
12

I've just discovered one more subtle difference between these two methods.

If module foo uses a following import:

from itertools import count

Then module bar can by mistake use count as though it was defined in foo, not in itertools:

import foo
foo.count()

If foo uses:

import itertools

the mistake is still possible, but less likely to be made. bar needs to:

import foo
foo.itertools.count()

This caused some troubles to me. I had a module that by mistake imported an exception from a module that did not define it, only imported it from other module (using from module import SomeException). When the import was no longer needed and removed, the offending module was broken.

Jan Wrobel
  • 6,969
  • 3
  • 37
  • 53
10

Here is another difference not mentioned. This is copied verbatim from http://docs.python.org/2/tutorial/modules.html

Note that when using

from package import item

the item can be either a submodule (or subpackage) of the package, or some other name defined in the package, like a function, class or variable. The import statement first tests whether the item is defined in the package; if not, it assumes it is a module and attempts to load it. If it fails to find it, an ImportError exception is raised.

Contrarily, when using syntax like

import item.subitem.subsubitem

each item except for the last must be a package; the last item can be a module or a package but can’t be a class or function or variable defined in the previous item.

user2141737
  • 607
  • 6
  • 5
  • Another thing I noticed was that if item is also a submodule inside package then "from package import item" works but "import package" package.item.subitem=... does not work with an empty __init__.py of package, unless we have "import item" in the __init__ file of package. – Amitoz Dandiana Dec 26 '18 at 14:57
8

Since I am also a beginner, I will be trying to explain this in a simple way: In Python, we have three types of import statements which are:

1. Generic imports:

import math

this type of import is my personal favorite, the only downside to this import technique is that if you need use any module's function you must use the following syntax:

math.sqrt(4)

of course, it increases the typing effort but as a beginner, it will help you to keep track of module and function associated with it, (a good text editor will reduce the typing effort significantly and is recommended).

Typing effort can be further reduced by using this import statement:

import math as m

now, instead of using math.sqrt() you can use m.sqrt().

2. Function imports:

from math import sqrt

this type of import is best suited if your code only needs to access single or few functions from the module, but for using any new item from the module you have to update import statement.

3. Universal imports:

from math import * 

Although it reduces typing effort significantly but is not recommended because it will fill your code with various functions from the module and their name could conflict with the name of user-defined functions. example:

If you have a function of your very own named sqrt and you import math, your function is safe: there is your sqrt and there is math.sqrt. If you do from math import *, however, you have a problem: namely, two different functions with the exact same name. Source: Codecademy

Community
  • 1
  • 1
Shashank Rawat
  • 1,371
  • 13
  • 15
7

I would like to add to this. It can be useful to understand how Python handles imported modules as attributes if you run into circular imports.

I have the following structure:

mod/
    __init__.py
    main.py
    a.py
    b.py
    c.py
    d.py

From main.py I will import the other modules using differnt import methods

main.py:

import mod.a
import mod.b as b
from mod import c
import d

dis.dis shows the difference (note module names, a b c d):

  1           0 LOAD_CONST               0 (-1)
              3 LOAD_CONST               1 (None)
              6 IMPORT_NAME              0 (mod.a)
              9 STORE_NAME               1 (mod)

  2          12 LOAD_CONST               0 (-1)
             15 LOAD_CONST               1 (None)
             18 IMPORT_NAME              2 (b)
             21 STORE_NAME               2 (b)

  3          24 LOAD_CONST               0 (-1)
             27 LOAD_CONST               2 (('c',))
             30 IMPORT_NAME              1 (mod)
             33 IMPORT_FROM              3 (c)
             36 STORE_NAME               3 (c)
             39 POP_TOP

  4          40 LOAD_CONST               0 (-1)
             43 LOAD_CONST               1 (None)
             46 IMPORT_NAME              4 (mod.d)
             49 LOAD_ATTR                5 (d)
             52 STORE_NAME               5 (d)
             55 LOAD_CONST               1 (None)

In the end they look the same (STORE_NAME is result in each example), but this is worth noting if you need to consider the following four circular imports:

example1

foo/
   __init__.py
   a.py
   b.py
a.py:
import foo.b 
b.py:
import foo.a
>>> import foo.a
>>>

This works

example2

bar/
   __init__.py
   a.py
   b.py
a.py:
import bar.b as b
b.py:
import bar.a as a
>>> import bar.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "bar\a.py", line 1, in <module>
    import bar.b as b
  File "bar\b.py", line 1, in <module>
    import bar.a as a
AttributeError: 'module' object has no attribute 'a'

No dice

example3

baz/
   __init__.py
   a.py
   b.py
a.py:
from baz import b
b.py:
from baz import a
>>> import baz.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "baz\a.py", line 1, in <module>
    from baz import b
  File "baz\b.py", line 1, in <module>
    from baz import a
ImportError: cannot import name a

Similar issue... but clearly from x import y is not the same as import import x.y as y

example4

qux/
   __init__.py
   a.py
   b.py
a.py:
import b 
b.py:
import a
>>> import qux.a
>>>

This one also works

ahfx
  • 348
  • 2
  • 9
  • 2
    Amazing fun fact! Can you explain the reason behind this? – Jzou Jan 06 '22 at 20:12
  • 1
    Good question! I don't know the answer off the top of my head, but that sounds like a fun exercise of spelunking through python internals. – ahfx Jan 17 '22 at 18:17
  • 1
    Only this answer provides some depth on the situation where the differences between the types of imports are so fundamental, that one is a "no go" (import-from), while other "works" (import, or from ... import *). Circular dependencies are unavoildable in some situations (e.g. where dependency injection is needed/used). For now it appears that import and from ... import * work as "include guards" in c++ (only need symbol names), but import-from statements actually require the target modules to be fully loaded. Need to get some more understanding on this... – P Marecki Oct 17 '22 at 12:57
  • 1
    .. it does not help that it is hard to find what "partially initialized module" is (on the level of module-load process(es)); ... with tons of results on how to "fix it", but little on how each of the three import statements actually proceed with the loading/initialization of modules... and whether this is mandated in the Language Reference, or just particular implementation _feature_ which can disappear in a puff.... with the next version of CPython (or other interpreter). – P Marecki Oct 17 '22 at 13:03
5
import package
import module

With import, the token must be a module (a file containing Python commands) or a package (a folder in the sys.path containing a file __init__.py.)

When there are subpackages:

import package1.package2.package
import package1.package2.module

the requirements for folder (package) or file (module) are the same, but the folder or file must be inside package2 which must be inside package1, and both package1 and package2 must contain __init__.py files. https://docs.python.org/2/tutorial/modules.html

With the from style of import:

from package1.package2 import package
from package1.package2 import module

the package or module enters the namespace of the file containing the import statement as module (or package) instead of package1.package2.module. You can always bind to a more convenient name:

a = big_package_name.subpackage.even_longer_subpackage_name.function

Only the from style of import permits you to name a particular function or variable:

from package3.module import some_function

is allowed, but

import package3.module.some_function 

is not allowed.

Bennett Brown
  • 5,234
  • 1
  • 27
  • 35
5

This is my directory structure of my current directory:

.  
└─a  
   └─b  
     └─c
  1. The import statement remembers all intermediate names.
    These names have to be qualified:

    In[1]: import a.b.c
    
    In[2]: a
    Out[2]: <module 'a' (namespace)>
    
    In[3]: a.b
    Out[3]: <module 'a.b' (namespace)>
    
    In[4]: a.b.c
    Out[4]: <module 'a.b.c' (namespace)>
    
  2. The from ... import ... statement remembers only the imported name.
    This name must not be qualified:

    In[1]: from a.b import c
    
    In[2]: a
    NameError: name 'a' is not defined
    
    In[2]: a.b
    NameError: name 'a' is not defined
    
    In[3]: a.b.c
    NameError: name 'a' is not defined
    
    In[4]: c
    Out[4]: <module 'a.b.c' (namespace)>
    

  • Note: Of course, I restarted my Python console between steps 1 and 2.
MarianD
  • 13,096
  • 12
  • 42
  • 54
4

To add to what people have said about from x import *: besides making it more difficult to tell where names came from, this throws off code checkers like Pylint. They will report those names as undefined variables.

DNS
  • 37,249
  • 18
  • 95
  • 132
4

My own answer to this depends mostly on first, how many different modules I'll be using. If i'm only going to use one or two, I'll often use from ... import since it makes for fewer keystrokes in the rest of the file, but if I'm going to make use of many different modules, I prefer just import because that means that each module reference is self-documenting. I can see where each symbol comes from without having to hunt around.

Usuaully I prefer the self documenting style of plain import and only change to from.. import when the number of times I have to type the module name grows above 10 to 20, even if there's only one module being imported.

SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
3

There have been many answers, but none have mentioned testing (with unittest or pytest).

tl;dr

Use import foo for external modules to simplify testing.

The Hard Way

Importing classes/functions (from foo import bar) individually from a module makes red-green-refactor cycles tedious. For example, if my file looks like

# my_module.py

from foo import bar


class Thing:
    def do_thing(self):
        bar('do a thing')

and my test is

# test_my_module.py

from unittest.mock import patch
import my_module


patch.object(my_module, 'bar')
def test_do_thing(mock_bar):
    my_module.Thing().do_thing()
    mock_bar.assert_called_with('do a thing')

At first glance, this seems great. But what happens if I want to implement Thing class in a different file? My structure would have to change like this...

# my_module.py

from tools import Thing


def do_thing():
    Thing().do_thing()


# tools.py

from foo import bar


class Thing:
    def do_thing(self):
        bar('do a thing')


# test_my_module.py

from unittest.mock import patch
import my_module
import tools  # Had to import implementation file...


patch.object(tools, 'bar')  # Changed patch
def test_do_thing(mock_bar):
    my_module.do_thing()  # Changed test (expected)
    mock_bar.assert_called_with('do a thing')

Unfortunately, since I used from foo import bar, I need to update my patch to reference the tools module. Essentially, since my test knows too much about implementation, much more than expected needs to be changed to do this refactor.

The Better Approach

Using import foo, my tests can ignore how the module is implemented and simply patch the whole module.

# my_module.py

from tools import Thing


def do_thing():
    Thing().do_thing()


# tools.py

import foo


class Thing:
    def do_thing(self):
        foo.bar('do a thing')  # Specify 'bar' is from 'foo' module


# test_my_module.py

from unittest.mock import patch
import my_module


patch('foo')  # Patch entire foo module
def test_do_thing(mock_foo):
    my_module.do_thing()  # Changed test (expected)
    mock_foo.bar.assert_called_with('do a thing')

The less implementation details your tests know, the better. That way, if you come up with a better solution (use classes instead of functions, use additional files to separate ideas, etc.), less needs to be changed in your tests to accommodate the refactor.

Chris Collett
  • 1,074
  • 10
  • 15
2

One of the significant difference I found out which surprisingly no-one has talked about is that using plain import you can access private variable and private functions from the imported module, which isn't possible with from-import statement.

enter image description here

Code in image:

setting.py

public_variable = 42
_private_variable = 141
def public_function():
    print("I'm a public function! yay!")
def _private_function():
    print("Ain't nobody accessing me from another module...usually")

plain_importer.py

import settings
print (settings._private_variable)
print (settings.public_variable)
settings.public_function()
settings._private_function()

# Prints:
# 141
# 42
# I'm a public function! yay!
# Ain't nobody accessing me from another module...usually

from_importer.py

from settings import *
#print (_private_variable) #doesn't work
print (public_variable)
public_function()
#_private_function()   #doesn't work
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
1

As Jan Wrobel mentions, one aspect of the different imports is in which way the imports are disclosed.

Module mymath

from math import gcd
...

Use of mymath:

import mymath
mymath.gcd(30, 42)  # will work though maybe not expected

If I imported gcd only for internal use, not to disclose it to users of mymath, this can be inconvenient. I have this pretty often, and in most cases I want to "keep my modules clean".

Apart from the proposal of Jan Wrobel to obscure this a bit more by using import math instead, I have started to hide imports from disclosure by using a leading underscore:

# for instance...
from math import gcd as _gcd
# or...
import math as _math

In larger projects this "best practice" allows my to exactly control what is disclosed to subsequent imports and what isn't. This keeps my modules clean and pays back at a certain size of project.

matheburg
  • 2,097
  • 1
  • 19
  • 46
1

since many people answered here but i am just trying my best :)

  1. import module is best when you don't know which item you have to import from module. In this way it may be difficult to debug when problem raises because you don't know which item have problem.

  2. form module import <foo> is best when you know which item you require to import and also helpful in more controlling using importing specific item according to your need. Using this way debugging may be easy because you know which item you imported.

M_x
  • 782
  • 1
  • 8
  • 26
0

Import Module - You don't need additional efforts to fetch another thing from module. It has disadvantages such as redundant typing

Module Import From - Less typing &More control over which items of a module can be accessed.To use a new item from the module you have to update your import statement.

Dlucidone
  • 1,091
  • 9
  • 23
0

There are some builtin modules that contain mostly bare functions (base64, math, os, shutil, sys, time, ...) and it is definitely a good practice to have these bare functions bound to some namespace and thus improve the readability of your code. Consider how more difficult is to understand the meaning of these functions without their namespace:

copysign(foo, bar)
monotonic()
copystat(foo, bar)

than when they are bound to some module:

math.copysign(foo, bar)
time.monotonic()
shutil.copystat(foo, bar)

Sometimes you even need the namespace to avoid conflicts between different modules (json.load vs. pickle.load)


On the other hand there are some modules that contain mostly classes (configparser, datetime, tempfile, zipfile, ...) and many of them make their class names self-explanatory enough:
configparser.RawConfigParser()
datetime.DateTime()
email.message.EmailMessage()
tempfile.NamedTemporaryFile()
zipfile.ZipFile()

so there can be a debate whether using these classes with the additional module namespace in your code adds some new information or just lengthens the code.

Jeyekomon
  • 2,878
  • 2
  • 27
  • 37
0

I was answering a similar question post but the poster deleted it before i could post. Here is one example to illustrate the differences.

Python libraries may have one or more files (modules). For exmaples,

package1
  |-- __init__.py

or

package2
  |-- __init__.py
  |-- module1.py
  |-- module2.py

We can define python functions or classes inside any of the files based design requirements.

Let's define

  1. func1() in __init__.py under mylibrary1, and
  2. foo() in module2.py under mylibrary2.

We can access func1() using one of these methods

import package1

package1.func1()

or

import package1 as my

my.func1()

or

from package1 import func1

func1()

or

from package1 import *

func1()

We can use one of these methods to access foo():

import package2.module2

package2.module2.foo()

or

import package2.module2 as mod2

mod2.foo()

or

from package2 import module2

module2.foo()

or

from package2 import module2 as mod2

mod2.foo()

or

from package2.module2 import *

foo()
yoonghm
  • 4,198
  • 1
  • 32
  • 48
0

In simple words, this is all about programmer convenience. At the core level, they simply import all functionality of the module.

import module: When you use import module then to use methods of this module you have to write module.method(). Every time you use any method or property then you have to refer to the module.

from module import all: When you use from module import all than to use methods of this module you just have to write method() without referring to the module.

Satish Chandra Gupta
  • 2,970
  • 1
  • 22
  • 22
0

There is a crucial aspect of these imports that @ahfx already mentioned, namely the internals of the process of loading modules. This pops up if your system needs to use circular imports (e.g. you want to make use of dependency injection in some popular http frameworks). In such cases the from {module} import {function} appears much more aggressive with its requirements on how the loading process proceeds. Let us take the example:

#m1.py:
print('--start-m1--')
from m2 import *    # form does not matter; just need to force import of m2
print('--mid-m1--')

def do1(x):
    print(x)

print('--end-m1--')

importing

#m2.py
print('--start-m2--')

# from m1 import *      # A
# from m1 import do1    # B
# import m1             # C
                        # D -- no import of "do1" at all
                        
print('--mid-m2--')

def do2(x):
    m1.do1(x)

print('--end-m2--')

run via

#main.py:
from m1 import do1
do1('ok')

Of all the import possibilities in m2.py (A,B,C,D), the from {module} import {function} is the only one that actually crashes the load process, leading to the infamous (CPython 3.10.6)

ImportError: cannot import name 'do1' from partially initialized module 'm1' 
(most likely due to a circular import)

While I cannot say why this happens, it appears that the from ... import ... statement puts a more stringent requirement on "how far" the module in question is already in its initialization process.

P Marecki
  • 1,108
  • 15
  • 19