【问题标题】:Python library project structure best practice: imports and testsPython 库项目结构最佳实践:导入和测试
【发布时间】:2016-12-10 22:48:40
【问题描述】:

我想重构一个我在日常工作中经常使用的 python 库,将它作为开源发布在 github 上。 在这样做之前,我想遵守某种 Python 项目结构的最佳实践。 我将在下面描述我想做的事情,我会很感激你的建议。

这是我的库(mylib)结构:

mylib/
   /examples/
       simple_example.py
   /mylib/
       __init__.py
       foo.py
       bar.py
   /tests/
       test_foo.py
       test_bar.py

这里是文件:

#foo.py
def Foo():
    print("foo.Foo")


#bar.py
import foo

def Bar():
    print("bar.Bar")
    foo.Foo()


#test_bar.py
from ..mylib import bar #doesnt work!

class TestBar(unittest.TestCase):
    def test_1(self):
        bar.Bar()
        self.assertEqual(True, True)

if __name__ == '__main__':
    unittest.main()


#simple_example.py
from .. import foo #doesnt work!
from .. import bar #doesnt work!

if __name__ == '__main__':  
    foo.Foo()
    bar.Bar()

我想做的是:

1- 理想情况下从 /mylib/examples/ 执行 simple_example.py:

$cd myapp
$cd examples
$python simple_example.py
Traceback (most recent call last):
  File "simple_example.py", line 2, in <module>
    from .. import foo
SystemError: Parent module '' not loaded, cannot perform relative import

2- 理想情况下从 /mylib/tests/ 执行单个测试文件:

$cd myapp
$cd tests
$python test_bar.py
Traceback (most recent call last):
  File "test_bar.py", line 3, in <module>
    from ..mylib import bar
SystemError: Parent module '' not loaded, cannot perform relative import    

3- 从 mylib 根目录执行所有测试

$cd myapp
$python -m unittest discover tests #same problem as above!

所以,问题出在 simple_example.py 和 test_bar.py 中的 import 语句中。 修复这些导入的最佳方法是什么?

请注意,我想使用 python 标准库 unittest 进行单元测试。

谢谢

查理

【问题讨论】:

    标签: python python-unittest project-structure


    【解决方案1】:

    在运行测试代码时,您希望进行绝对导入。这是因为当您运行单元测试等时,您应该假设您的“库”安装在本地开发模式下进行测试——不要使用相对导入,因为您不在同一个包中。

    以下是在 test_foo.py 文件中导入的方法,例如:

    # test_foo.py
    from mylib.foo import Foo
    
    # ... your test code here
    

    一般来说,您应该只在库代码内部使用相对导入,而不是在测试中使用 =)

    我希望这会有所帮助。

    编辑:您还需要在开发模式下安装库,然后才能使用。您可以通过以下两种方式之一执行此操作:

    $ python setup.py develop
    

    $ pip install -e .
    

    上述任一命令都将检查您项目的 setup.py 文件,该文件告诉 Python 您的包是如何构建/创建的,并将在本地安装它,以便您可以运行测试/弄乱它。

    【讨论】:

    • 可能是我遗漏了一些东西(例如调整 sys.path),但使用您的解决方案我仍然收到错误 ImportError: No module named mylib.foo
    • 你必须先在开发模式下安装你的库。您需要在运行任何测试之前运行python setup.py develop。我会更新我的答案以反映这一点。
    • 但是从 bar.py 你需要使用from . import foo。注意我使用的是 python 3.5。请参阅 David Beazley 在 PyCon2015 youtube.com/watch?v=0oTh1CXRaQ0 分钟 17:40 的演讲!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多