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.