Python导入,包和可运行脚本

时间:2015-12-21 21:46:34

标签: python python-import

我已阅读以下帖子:

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需要以某种方式导入main1main1需要以某种方式导入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,因此不能像我提到的那样作为独立脚本运行。

对于我的可运行脚本的导入,干净的解决方案是什么?

2 个答案:

答案 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

这假定

  1. 您正在使用unittest
  2. 您的测试子类unittest.TestCase
  3. 您使用的是默认课程unittest.TestLoader