0

This is very basic question which has a very extensive answer written by @Mark Roddy Use 'import module' or 'from module import'?

According to this answer there are pros and cons to each method but the result is equivalent and both work.

so doing:

import module

or

from module import foo

should work.

My Question:

Consider this example:

import distutils
print (distutils.util.strtobool('true'))

Which gives:

> Traceback (most recent call last):   File "<stdin>", line 1, in
> <module> AttributeError: module 'distutils' has no attribute 'util'

And:

from distutils.util import strtobool
print (strtobool('true'))

Which gives following ouput:

1

So I'm confused. Both should work. Why Python generates an exception for the first approach?

Luis
  • 1,305
  • 5
  • 19
  • 46

2 Answers2

3

If you import A, and then try to access A.B, then B must be a valid attribute present in module A. For instance:

# A.py
from . import B
# or
B = 'foo'

If A contains the above code, then inside A, B is a valid local name and by extension an accessible attribute of module A. However, if module A does not define any B, then you can't access it when you import A.

Now, import A.B or from A.B import ... explicitly looks not at the attributes of the modules, but at the files and folders. So even if inside A.py there's no symbol B defined, as long as there's a file B.py or folder B, import will import it.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • Thanks! I think this should be also added to the refereed question. This is important information which is missing there – Luis Feb 13 '19 at 10:01
3

These are equivalent:

from mod import val
val

import mod
mod.val

As are these:

from mod1.mod2 import val
val

import mod1.mod2
mod1.mod2.val

But this doesn't work, as mod2 is not imported:

import mod1
mod1.mod2.val

If you add import mod2 inside mod1.py (or mod1/__init__.py), then mod2 becomes a value exported by mod1, and the last example will work. distutils does not import distutils.util, so you have to import it yourself in order to gain access to its exported members.

Amadan
  • 191,408
  • 23
  • 240
  • 301