我对python import语句有点奇怪。
我们说我的文件结构如下:
foo\
__init__.py
bar.py
os.py
bar.py中的代码(其他文件为空)
import os
print os.__file__
奇怪的是,当我运行python -m foo.bar
时,它会打印
foo/os.pyc
但是,当我将direcotry更改为foo
并运行python -m bar
时,会打印
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc
我运行脚本的两种方式有什么区别?
总之, Python用于导入模块的顺序是什么?
从官方文件中,我发现了几个关于这个问题的文字(他们让我更加困惑)
解释程序首先搜索具有该名称的内置模块。如果未找到,则会在变量 sys.path 给出的目录列表中搜索名为spam.py的文件。
此列表的第一项path [0]是包含用于调用Python解释器的脚本的目录。如果脚本目录不可用(例如,如果以交互方式调用解释器或者从标准输入读取脚本),则路径[0]为空字符串,指示Python首先搜索当前目录中的模块。
事实上,在查看标准模块搜索路径之前,这样的引用很常见,导入语句首先在包含的包中查找。
...
如果在当前包(当前模块是子模块的包)中找不到导入的模块,则import语句将查找具有给定名称的顶级模块。 / p>
答案 0 :(得分:5)
我运行脚本的两种方式之间有什么区别?
不同之处在于foo
是否(来自python的视图)是否已加载模块。
如果您运行python -m foo.bar
,则foo
是有效的模块。即使使用Python 2.7,import os
仍然是relative import,因此os
会针对包含模块(即foo
)进行解析,首先:
https://docs.python.org/2/tutorial/modules.html#intra-package-references:
子模块通常需要相互引用。例如,环绕声模块可能使用echo模块。实际上,这样的引用是如此常见,以至于在查看标准模块搜索路径之前,import语句首先在包含包中查找。
当您运行python -m bar
时,bar
是顶级模块,即它没有包含模块。在这种情况下,import os
会通过sys.path
。
import bla
的默认模块搜索是
sys.path
并使用第一次成功导入。要禁用(1),您可以
from __future__ import absolute_import
位于模块的最顶层。
混淆?绝对