为什么使用-m选项调用模块会将sys.path[0]设置为字符串空值?

6 投票
1 回答
831 浏览
提问于 2025-04-17 20:39

我在当前目录 C:\test 下有一个 Python 脚本 foo.py

这是代码。

import sys
print('sys.path:', sys.path)
print('sys.argv:', sys.argv)

当我把它当作脚本执行时,看到的输出是这样的。

C:\test>python foo.py
sys.path: ['C:\\test', 'C:\\Windows\\system32\\python34.zip', 'C:\\Python34\\DLLs', 'C:\\Python34\\lib', 'C:\\Python34', 'C:\\Python34\\lib\\site-packages']
sys.argv: ['foo.py']

但是当我把它当作模块执行时,看到的输出却是这样的。

C:\test>python -m foo
sys.path: ['', 'C:\\Windows\\system32\\python34.zip', 'C:\\Python34\\DLLs', 'C:\\Python34\\lib', 'C:\\Python34', 'C:\\Python34\\lib\\site-packages']
sys.argv: ['C:\\test\\foo.py']

为什么当我把程序当作模块执行时,sys.path[0] 变成了空字符串呢?

文档中提到,http://docs.python.org/3.4/library/sys.html#sys.path 说:

在程序启动时初始化时,这个列表的第一个项目 path[0] 是包含用来调用 Python 解释器的脚本的目录。如果脚本目录不可用(例如,如果解释器是以交互方式调用的,或者脚本是从标准输入读取的),那么 path[0] 就会是空字符串,这样 Python 会优先在当前目录中查找模块。

所以只有在脚本目录不可用的情况下,sys.path[0] 才会被设置为 ''。但在我的情况下,即使我执行 python -m foo,脚本目录 foo 显然是可用的。因此,按照文档的说法,它不应该把 sys.path[0] 设置为 '',而应该设置为 'C:\\test'

这是文档的错误,还是 Python 解释器的错误,还是我理解错了呢?

1 个回答

7

看看 man python-m 的解释:

-m module-name

sys.path 中查找指定的模块,并将对应的 .py 文件作为脚本运行。

想想看,把要运行的 .py 文件所在的目录加到 sys.path 中其实没有意义,因为它本来就得在那儿才能被找到。所以,我认为这个行为是正确的。

不过,文档上说如果它作为脚本运行,包含它的目录应该被放到 sys.path 的前面。我觉得文档上这点是个错误,应该这样说:

[...](例如,如果解释器是以交互方式调用的,或者如果脚本是从标准输入读取的 或者如果脚本是使用 -m 选项运行的)[...]

撰写回答