使用doctests导入Python项目

时间:2010-03-03 14:40:00

标签: python linux unix path

我有一个具有以下目录结构的Python项目:

/(some files)
/model/(python files)
/tools/(more python files)
...

所以,我在几个子目录中有Python文件,还有一些 目录之间的依赖关系:工具由模型等使用。现在 我的问题是我想为模型工具进行doctests, 我希望能够从命令行运行测试,如下所示: ./ model / car.py 。 我可以使这个工作,但只有凌乱的样板代码。我想要 知道什么是 正确的方法,还是有什么?

问题:我应该如何编写我的导入文件?

感谢名单。这是一个例子......

tools / tool.py 的内容:

#!/usr/bin/env python
"""
   >>> is_four(21)
   False
   >>> is_four(4)
   True
"""

def is_four(val):
    return val == 4

if __name__ == '__main__':
    import doctest
    doctest.testmod()

...和 model / car.py

#!/usr/bin/env python   
"""
   >>> car = Car()
   >>> car.ok()
   True
"""

from tools.tool import *

class Car(object):
    def __init__(self):
        self.tire_count = 4
    def ok(self):
        return is_four(self.tire_count)

if __name__ == '__main__':
    import doctest
    doctest.testmod()

通过在car.py的开头添加以下行,它可以工作,但看起来不太好。 :(

if __name__ == '__main__':
    import sys
    import os
    sys.path.append(os.path.abspath(os.path.dirname('..')))

3 个答案:

答案 0 :(得分:2)

您要做的是相对导入。它在Python中运行良好,但在模块级别,而不是在文件系统级别。我知道,这很令人困惑。

这意味着如果你在一个子目录中运行一个脚本,它就不会看到上层目录,因为对于正在运行的脚本,模块的根目录是当前目录:没有上层模块。

那么相对进口是什么?

嗯,只要它们是从上层导入的,就可以在上层目录中的子目录中导入模块。

在您的情况下,这意味着您必须从“/”运行脚本,以便它成为模块的根目录,并允许子模块使用相对导入。

问题的一个可能解决方案是删除if __name__ == "__main__"块并创建/tests.py:

import doctest
from model import car
from tools import tool

doctest.testmod(car)
doctest.testmod(tool)

然后运行也启动所有测试。

最终你需要自动化这个过程,一个简单的解决方案是使用unittest,这样你就可以创建测试套件,只需添加你想要测试的模块名称:

import unittest
import doctest

modules = ("model.car", 
           "tools.tool")

suite = unittest.TestSuite()
for mod in modules:
    suite.addTest(doctest.DocTestSuite(mod))
runner = unittest.TextTestRunner()
runner.run(suite)

另一种解决方案(推荐)是使用nose等工具为您自动执行此操作。

easy_install nose
nosetests --with-doctest # done :-)

顺便说一下,避免from x import *。这适用于快速脚本,但是当程序增长时,您确实需要明确命名导入的内容。 import xfrom x import y

答案 1 :(得分:1)

使用包裹。将__init__.py文件添加到您的工作目录和所有子文件夹,然后如果在当前目录中找不到该模块,您的导入将搜索父目录。

请参阅http://www.network-theory.co.uk/docs/pytut/Packages.html

此问题也与以下内容重复:

Import a module from a relative path

答案 2 :(得分:0)

不要以这种方式欺骗sys.path。而是在调用$PYTHONPATH时使用python强制基本目录,或者使用该目录中的python -m model.car