Python导入,包和运行的脚本

问题描述:

我读过下面的帖子:Python导入,包和运行的脚本

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,因此不能像我提到的那样作为独立脚本运行。

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

典型的方法是将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 
+0

我曾经想过通过一些'testenv'模块来做这件事,所有的测试都会先导入,但看起来不够好看 – DoomMuffins

库,如内置unittest有内置的测试发现。默认情况下,它希望测试位于以test*.py模式命名的文件中,其中星号(*)可以是任何您想要的。然后,您会使用discover和使用运行包:

python -m unittest discover 

这假定

  1. 您使用unittest
  2. 你的测试子类unittest.TestCase
  3. 您使用默认类unittest.TestLoader