为什么 python 只有在我使用 -m 标志时才能正确导入?

Why does python only correctly import if I'm using -m flag?

我目前对 python 中的导入是如何工作的非常困惑。基本上,我很困惑为什么将脚本作为模块启动(使用 -m)会改变行为: 我在名为 Testing 的文件夹中有两个脚本。一个名为 Programm.py,另一个名为 Test_Programm.py.

Test_Programm.py中的第一行是:from Testing.Programm import my_function

运行 Test_Programm.py 来自 Testing 的父文件夹,使用命令行 python -m Testing。 Test_Programm 按预期工作,它按预期导入所有内容。 运行 它来自带有 python -m Test_Programm 的 Testing 文件夹,无法导入。 运行 它来自父文件夹,因为 python Testing\Test_Programm.py 不起作用。当 运行 在 python Test_Programm.py.

的测试文件夹中时,它也不起作用

这是为什么呢,python如何寻找模块?

所有测试均使用 Python 3.8.0

完成

堆栈跟踪:

python Testing\Test_Programm.py 在父文件夹中:

Traceback (most recent call last):
  File "Testing\Test_Programm.py", line 8, in <module>
    from Testing.Test_Programm import my_function
ModuleNotFoundError: No module named 'Testing'

python Test_Programm.py 在测试文件夹中:

Traceback (most recent call last):
  File "Test_Programm.py", line 8, in <module>
    from Test_Programm import my_function
ModuleNotFoundError: No module named 'Testing'

python -m Test_Programm.py 在测试文件夹中:

Traceback (most recent call last):
  File "C:\Python38\lib\runpy.py", line 192, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Python38\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\<username>\PycharmProjects\TestingTesting\src\Testing\Test_Programm.py", line 8, in <module>
    from Testing.Test_Programm import my_function
ModuleNotFoundError: No module named 'Testing'

根据 the sys.path documentation:

As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first.

根据 the Python command-line documentation:

When called with -m module-name, the given module is located on the Python module path and executed as a script.

第二个引用的含义是 -m 调用方法不是 sys.path 描述它的意义上的“运行ning 脚本”,因为它必须设置sys.path,再找要执行的模块,所以不能让path[0]匹配脚本目录(sys.path一般不会在解释器初始设置后由 Python 本身以编程方式修改,然后是 site 模块)。

在他们两个之间,这回答了你的问题。由于您的目录不是“始终在线”sys.path 的一部分,因此您依赖于 sys.path.

中第一个条目的隐式行为

个案是:

  1. 运行 python3 Testing/Test_Programm.pysys.path[0]Testing/,因此当您从 Testing.Programm 导入时,在 [=10] 中找不到任何条目=] 带有 Testing 子目录,它放弃了(python3 Test_Programm.py 也是如此;脚本文件夹中没有 Testing
  2. 来自同一目录的
  3. 运行 python3 -mTest_Programm 也不起作用; sys.path[0] 是先搜索当前目录,再一次,没有 Testing 子目录
  4. python3 -mTesting.Test_Programm 工作是因为它查找 运行 的模块,而不是直接执行脚本,所以 path[0] 仍然是工作目录, 有一个 Testing 子目录。它找到它,在它里面找到 Test_Programm.py,当它 运行 时,它 仍然 根搜索 Testing 所以从 Testing.Programm 工作。