Use import module or import from module?

Keywords: Python

I'm trying to find a comprehensive guide to see if it's best to use import module or from module import? I've just started using Python, and I'm trying to focus on best practices.

Basically, I want someone to share their experience, what do other developers like, and what's the best way to avoid trouble in the future?

#1 building

I have just discovered another nuance between the two methods.

If the module foo uses the following import:

from itertools import count

Then, the module bar may mistakenly use count as if it were defined in foo, not in itertools:

import foo
foo.count()

If foo uses:

import itertools

The error is still possible, but unlikely. bar needs:

import foo
foo.itertools.count()

This brings me trouble. I have a module that mistakenly imports an exception from a module that does not define an exception, only from module import SomeException. When you no longer need to import and delete it, the problematic module will be destroyed.

#2 building

There is another detail, not mentioned, related to the write module. Of course, this may not be very common, but I need it from time to time.

Because of how references and names bind in Python, if you want to update some symbols in a module (such as foo.bar) from outside the module and change other import code "see", you must import foo in some 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 a symbol name instead of a module name, it cannot be used.

For example, if I do this in module a:

from foo import bar
bar = "oranges"

No code other than a will treat bar as "orange" because my setting of bar only affects the name "bar" in module a, which does not "enter" the foo module object and update its "bar".

#3 building

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

Please note that when using

from package import item

The project can be a sub module (or sub package) of the package or another name defined in the package, such as a function, class, or variable. The import statement first tests whether the project is defined in the wrapper; if not, assume it is a module and try to load it. If it is not found, an ImportError exception is thrown.

Instead, when using similar

import item.subitem.subsubitem

Each project must be a wrapper, except for the last project; the last project can be a module or package, but not a class or function or variable defined in the previous project.

#4 building

Even though many people have explained import from, I'd like to try to explain more about what happened behind the scenes and all the changes it has made.

import foo :

Import foo and create a reference to the module in the current namespace. Then, you need to define the full module path to access specific properties or methods from within the module.

For example foo.bar but not bar

from foo import bar :

Import Foo and create a reference (bar) to all members listed. The variable foo is not set.

For example bar but not Baz or foo.baz

from foo import * :

Import Foo and create a reference to all the public objects defined by the module in the current namespace (if there is any, all the contents listed in all, otherwise all the contents that do not start with). The variable foo is not set.

For example bar and baz but not ﹣ qux or foo. ﹣ qux.

Now let's see when to import XY:

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

The check names are OS and os.path sys.modules:

>>> 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'>

Use os and os.path to check the global () and local () namespace Dictionaries:

 >>> 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 find that only os inserts local and global namespaces. Therefore, 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 the OS is removed from the locals() namespace, the OS and os.path cannot be accessed even if 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

Use OS and os.path to check sys.modules:

>>> 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 used import name to find the same result as before

OK, let's check its appearance in the locals() and globals() namespace Dictionaries:

>>> 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 use the name path instead of 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 remove 'path' from places():

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

Last example of using aliases:

>>> 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'
>>>

#5 building

import package
import module

With import, the token must be a module (a file that contains Python commands) or a package (a folder where sys.path contains the file \.

With 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 in package2, package2 must be in package1, and package1 and package2 must contain the \. https://docs.python.org/2/tutorial/modules.html

from import style:

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

Package or module input 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 import style allows you to name specific functions or variables:

from package3.module import some_function

Allowed, but

import package3.module.some_function 

Not allow.

Posted by rkrass on Tue, 18 Feb 2020 03:29:20 -0800