一般模块导入规则
import xxx 时搜索文件的优先级如下 1. The home directory of the program 2. PYTHONPATH directories (if set) 3. Standard library directories 4. The contents of any .pth files (if present) 5. The site-packages home of third-party extensions top-level file 指的是 main 模块文件。 sys.path 是模块搜索的 PATH ,在 Python 程序启动时进行配置,自动将 top-level file 的 home 目录(或用一个''表示当前工作目录)、PYTHONPATH 设置的目录、.pth 文件里的目录、标准库目录 合并成一个 list ,组成每次 import 时 Python 搜索的目录列表。
sys.path
# '' 表示是当前目录 [root@localhost ~]# python Python 2.6.6 (r266:84292, Nov 22 2013, 12:16:22) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> >>> import sys >>> >>> sys.path ['', '/usr/lib/python2.6/site-packages/setuptools-9.1-py2.6.egg', '/usr/lib/python2.6/site-packages/certifi-2015.9.6-py2.6.egg', '/usr/lib/python2.6/site-packages/futures-3.0.3-py2.6.egg', '/usr/lib/python2.6/site-packages/requests_futures-0.9.5-py2.6.egg', '/usr/lib/python2.6/site-packages/six-1.8.0-py2.6.egg', '/usr/lib/python2.6/site-packages/singledispatch-3.4.0.3-py2.6.egg', '/usr/lib/python2.6/site-packages/Tornado_MySQL-0.5-py2.6.egg', '/usr/lib/python2.6/site-packages/suds-0.4-py2.6.egg', '/usr/lib/python2.6/site-packages/bigsuds-1.0.3-py2.6.egg', '/usr/lib64/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/lib64/python2.6/site-packages/gst-0.10', '/usr/lib64/python2.6/site-packages/gtk-2.0', '/usr/lib64/python2.6/site-packages/webkit-1.0', '/usr/lib/python2.6/site-packages'] >>> exit() [root@localhost ~]# [root@localhost ~]# python3 python3 python34 [root@localhost ~]# python34 Python 3.4.3 (default, Oct 8 2015, 17:58:21) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> >>> import sys >>> >>> sys.path ['', '/usr/local/python34/lib/python3.4/site-packages/Django-1.8.5-py3.4.egg', '/usr/local/python34/lib/python3.4/site-packages/tornado-4.2.1-py3.4-linux-x86_64.egg', '/usr/local/python34/lib/python34.zip', '/usr/local/python34/lib/python3.4', '/usr/local/python34/lib/python3.4/plat-linux', '/usr/local/python34/lib/python3.4/lib-dynload', '/usr/local/python34/lib/python3.4/site-packages'] >>>
参考
--官方 http://legacy.python.org/dev/peps/pep-0328/ --stackoverflow http://stackoverflow.com/questions/33743880/what-does-from-future-import-absolute-import-actually-do
总结
相对导入,表示只在 package 的内部目录中搜索,并且不会搜索位于 sys.path 上某处同名的模块,直接效果就是包模块覆盖了外部的模块。 绝对导入,表示在 sys.path 中搜索。 Python 2.6 中,包的代码中的常规导入(没有前面的点号),目前默认为先相对再绝对 的搜索顺序,然而在 3.0 中,在一个包中导入默认是绝对的,在缺少点语法的时候,导入忽略了包自身的搜索,在 sys.path 目录里搜索。 from __future__ import absolute_import,表示打开了 Python 3.0 的默认绝对搜索路径特性。 1. 从一个 module 导入多个 names,用括号将多个 names 包围 from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text, LEFT, DISABLED, NORMAL, RIDGE, END) 2. from __future__ import absolute_import means that if you import string, Python will always look for a top-level string module, rather than current_package.string. However, it does not affect the logic Python uses to decide what file is the string module. 3. python pkg/main2.py 和 python pkg.main2 的行为是不一样的 pkg/ pkg/__init__.py pkg/main.py pkg/string.py python pkg/main2.py 在 Python 看起来并不是 package 形式,所以是按常规程序对待的,pkg 目录会被加入到 sys.path ,pgk 目录下所以 .py 结尾的文件都被视为 top-level 模块, 这时 import string 将找到 pkg/string.py,并不是因为相对导入,而是因为 pkg/string.py 出现在 top-level ,结果是标准 string 模块没有被导入。 python -m pkg.main2 是 package ,pkg 目录不会加入到 sys.path ,而是将 current directory 添加到 sys.path。 所以 python pkg/main2.py 和 python -m pkg.main2 的 top-level 是不一样的,影响搜索路径。 import pkg.main2 相当于解释器使用的 -m 开关 # [root@localhost Music]# pwd /root/Music [root@localhost Music]# cat pkg/main1.py #import string;print(string.ascii_uppercase) import sys print sys.path [root@localhost Music]# cat pkg/main2.py from __future__ import absolute_import #import string;print(string.ascii_uppercase) import sys print sys.path [root@localhost Music]# [root@localhost Music]# python pkg/main1.py ['/root/Music/pkg', '/usr/lib/python2.6/site-packages/setuptools-9.1-py2.6.egg', '/usr/lib/python2.6/site-packages/certifi-2015.9.6-py2.6.egg', '/usr/lib/python2.6/site-packages/futures-3.0.3-py2.6.egg', '/usr/lib/python2.6/site-packages/requests_futures-0.9.5-py2.6.egg', '/usr/lib/python2.6/site-packages/six-1.8.0-py2.6.egg', '/usr/lib/python2.6/site-packages/singledispatch-3.4.0.3-py2.6.egg', '/usr/lib/python2.6/site-packages/Tornado_MySQL-0.5-py2.6.egg', '/usr/lib/python2.6/site-packages/suds-0.4-py2.6.egg', '/usr/lib/python2.6/site-packages/bigsuds-1.0.3-py2.6.egg', '/usr/lib64/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/lib64/python2.6/site-packages/gst-0.10', '/usr/lib64/python2.6/site-packages/gtk-2.0', '/usr/lib64/python2.6/site-packages/webkit-1.0', '/usr/lib/python2.6/site-packages'] [root@localhost Music]# [root@localhost Music]# python -m pkg.main1 ['', '/usr/lib/python2.6/site-packages/setuptools-9.1-py2.6.egg', '/usr/lib/python2.6/site-packages/certifi-2015.9.6-py2.6.egg', '/usr/lib/python2.6/site-packages/futures-3.0.3-py2.6.egg', '/usr/lib/python2.6/site-packages/requests_futures-0.9.5-py2.6.egg', '/usr/lib/python2.6/site-packages/six-1.8.0-py2.6.egg', '/usr/lib/python2.6/site-packages/singledispatch-3.4.0.3-py2.6.egg', '/usr/lib/python2.6/site-packages/Tornado_MySQL-0.5-py2.6.egg', '/usr/lib/python2.6/site-packages/suds-0.4-py2.6.egg', '/usr/lib/python2.6/site-packages/bigsuds-1.0.3-py2.6.egg', '/usr/lib64/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/lib64/python2.6/site-packages/gst-0.10', '/usr/lib64/python2.6/site-packages/gtk-2.0', '/usr/lib64/python2.6/site-packages/webkit-1.0', '/usr/lib/python2.6/site-packages'] [root@localhost Music]#
解释
In Python 2.6, any import statement that results in an intra-package import will raise DeprecationWarning (this also applies to from <> import that fails to use the relative import syntax). Note that python2 pkg/main2.py has a different behaviour then launching python2 and then importing pkg.main2 (which is equivalent to using the -m switch). If you ever want to run a submodule of a package always use the -m switch which prevents the interpreter for chaning the sys.path list and correctly handles the semantics of the submodule. Also, I much prefer using explicit relative imports for package submodules since they provide more semantics and better error messages in case of failure.
[root@localhost Music]# mkdir pkg [root@localhost Music]# touch pkg/__init__.py [root@localhost Music]# touch pkg/string.py [root@localhost Music]# echo 'import string;print(string.ascii_uppercase)' > pkg/main1.py [root@localhost Music]# python Python 2.6.6 (r266:84292, Nov 22 2013, 12:16:22) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> >>> import pkg.main1 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "pkg/main1.py", line 1, in <module> import string;print(string.ascii_uppercase) AttributeError: 'module' object has no attribute 'ascii_uppercase' >>> exit() [root@localhost Music]# echo 'from __future__ import absolute_import;import string;print(string.ascii_uppercase)' > pkg/main2.py [root@localhost Music]# python Python 2.6.6 (r266:84292, Nov 22 2013, 12:16:22) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> >>> import pkg.main2 ABCDEFGHIJKLMNOPQRSTUVWXYZ >>> exit() [root@localhost Music]# [root@localhost Music]# python pkg/main2.py Traceback (most recent call last): File "pkg/main2.py", line 1, in <module> from __future__ import absolute_import;import string;print(string.ascii_uppercase) AttributeError: 'module' object has no attribute 'ascii_uppercase' [root@localhost Music]# [root@localhost Music]# python Python 2.6.6 (r266:84292, Nov 22 2013, 12:16:22) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> >>> import pkg.main2 ABCDEFGHIJKLMNOPQRSTUVWXYZ >>> exit() [root@localhost Music]# [root@localhost Music]# python -m pkg.main2 ABCDEFGHIJKLMNOPQRSTUVWXYZ [root@localhost Music]# [root@localhost Music]#