我已阅读以下帖子:
Relative imports for the billionth time
它解释了将文件作为顶级脚本运行并将其作为模块导入的区别非常明显和细节。
但是,我无法弄清楚如何编写可运行脚本(if __name__ == '__main__'
等等)的导入,我也可以从我的测试中导入它,保持我的可运行脚本独立(即不需要安装包)。
说我有以下项目层次结构:
/reporoot
/mypkg
/mysubpkg
__init__.py
subpkgmodule.py
__init__.py
main1.py
main2.py
/tests
test_main1.py
test_main2.py
test_main1
需要以某种方式导入main1
,main1
需要以某种方式导入subpkgmodule
。
例如,如果main1
导入subpkgmodule
,请执行以下操作:
import mysubpkg.subpkgmodule
这在将脚本作为顶级脚本运行时可以正常工作,因为顶级脚本的目录已添加到sys.path
。但是,当导入模块而不是运行模块时,此导入将中断(因为其目录不会添加到sys.path
)。
如果main1
导入subpkgmodule
,请执行以下操作:
import mypkg.mysubpkg.subpkgmodule
这仅在包是已安装的包(包括python setup.py develop
)且不作为独立脚本运行时运行(即将其放在某个文件系统上并运行python main1.py
)。
我看到标准库的http.server
模块有import http.client
,因此不能像我提到的那样作为独立脚本运行。
对于我的可运行脚本的导入,干净的解决方案是什么?
答案 0 :(得分:1)
典型的方法是在runnable脚本中扩展sys.path
和包的位置。
指定模块搜索路径的字符串列表。 从环境变量PYTHONPATH初始化,再加上一个 与安装相关的默认值。
在程序启动时初始化,此列表的第一项, path [0],是包含用于的脚本的目录 调用Python解释器。如果脚本目录不是 可用的(例如,如果以交互方式调用解释器,或者如果是 脚本是从标准输入读取的),path [0]是空字符串, 它指示Python首先搜索当前目录中的模块。 请注意,脚本目录在条目之前插入 由于PYTHONPATH而被插入。
程序可以自行修改此列表。
示例test_main1.py
:
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
import mypkg.mysubpkg.subpkgmodule # should import fine
if __name__ == "__main__":
pass # runnable code here
答案 1 :(得分:0)
内置unittest
等库具有内置测试发现功能。默认情况下,它希望测试位于以模式test*.py
命名的文件中,其中星号(*)可能是您喜欢的任何内容。然后,您使用discover
并使用以下命令运行包:
python -m unittest discover
这假定
unittest
,unittest.TestCase
和unittest.TestLoader
。