Ana*_*and 5 python python-import pythonpath language-lawyer
如果您从命令行(带有-c标志)或通过指定模块路径(带有-m标志)作为单个命令启动 Python 进程,则工作目录将附加到sys.path. 从文档(强调我的):
-c <命令>
[...]
如果给出这个选项,第一个元素
sys.argvwill"-c"和当前目录将被添加到开头sys.path(允许该目录中的模块作为顶级模块导入)。[...]
-m <模块名称>
[...]
如果给出此选项,则 的第一个元素
sys.argv将是模块文件的完整路径(在定位模块文件时,第一个元素将设置为"-m")。与-c选项一样, 当前目录将被添加到sys.path.[...]
但似乎每个选项的完成方式都不同:
$ python -c "import sys; print sys.path"
['', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/home/plammens/.local/lib/python3.8/site-packages', '/usr/local/lib/python3.8/dist-packages', '/usr/lib/python3/dist-packages']
$ python -m script # script.py does the same as the command above
['/mnt/c/Users/Paolo/Desktop/Code Sandbox/Python/clean', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/home/plammens/.local/lib/python3.8/site-packages', '/usr/local/lib/python3.8/dist-packages', '/usr/lib/python3/dist-packages']
Run Code Online (Sandbox Code Playgroud)
请注意第一个选项如何使用空字符串来表示当前工作目录,而第二个选项则明确地将路径添加到我运行命令的目录中。
根据导入系统上的文档,在执行期间始终动态解释空字符串以表示当前工作目录:
当前工作目录(由空字符串表示)的处理方式与 上的其他条目略有不同
sys.path。首先,如果发现当前工作目录不存在,则不存储任何值sys.path_importer_cache。其次,对于每个模块 lookup 都会重新查找当前工作目录的值。第三,用于sys.path_importer_cache和返回 的路径importlib.machinery.PathFinder.find_spec()将是实际的当前工作目录,而不是空字符串。
所以这意味着-c版本将始终使用 Python 进程的当前工作目录,而不是它最初启动的目录。
事实上,我们可以举一个例子来说明这一点。考虑以下文件树,
.
??? script.py
??? secret-folder
??? findme.py
Run Code Online (Sandbox Code Playgroud)
与findme.py只包含一个声明print("you found me!")。如果我们运行以下
import os
os.chdir('secret-folder')
import findme
Run Code Online (Sandbox Code Playgroud)
作为命令 ( -c) 和脚本 (in script.py),我们得到:
$ python -c "import os; os.chdir('secret-folder'); import findme"
you found me!
$ python -m script
Traceback (most recent call last):
File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/.../script.py", line 5, in <module>
import findme
ModuleNotFoundError: No module named 'findme'
Run Code Online (Sandbox Code Playgroud)
这是因为-m正在使用“硬编码”工作目录,同时-c使用“动态解释”当前目录。
通过它在文档中的措辞-c和方式-m,人们会认为这两者的行为应该相同。
这是故意的吗?如果是这样,则没有记录。
更新-在 BPO 上打开了一个问题。