当我运行类似python -m moduala.test
和python moduala/testa.py
的程序时,我在python3中看到了不同的包处理行为。在-m的情况下,testa.py中moduala.modualb.pkgx的导入有效,而在另一种情况下则不起作用。
python --version
# Python 3.6.9
mkdir -p testpyproj/pkga/pkgb
cd testpyproj/
touch pkga/__init__.py
touch pkga/pkgb/__init__.py
echo 'print("# python!")' >pkga/pkgb/modx.py
echo 'from pkga.pkgb import modx' > pkga/test.py
python -m pkga.test
# python!
python pkga/test.py
# Traceback (most recent call last):
# File "pkga/test.py", line 1, in <module>
# from pkga.pkgb import modx
# ImportError: No module named pkga.pkgb
从手册页来看,我希望这些都是一样的:
-m module-name Searches sys.path for the named module and runs the corresponding .py file as a script.
在加载模块和处理包方面,python-m和python[file]有什么区别?
为什么python[文件]找不到pkga.pkgb?
当python从命令行运行脚本时,如:
$ python pkga/test.py
it知道它正在运行一个相对的脚本因此,它将sys.path[0]
的值更改为脚本的目录
当python从命令行打开一个模块时,它必须有一个模块搜索路径(也称为sys.path
(才能找到该模块。因此它将CCD_ 5设置为CCD_;当前目录";。然后,它搜索sys.path
指示的所有位置,试图找到您给定的模块名称。
这样做的结果是,在一种情况下,您的sys.path[0]
将是""
,而在另一种情况中,它将是/path/to/current/directory/pkga
。然后,当搜索路径从该位置开始时,它不能解析pkga.pkgb
。
您可以通过添加以下内容来确认:
import sys
print(sys.path)
到pkga/test.py
的开始,在任何其他导入之前。您将在模块导入异常之前看到打印输出。