Python 库项目结构最佳实践:导入和测试
Python library project structure best practice: imports and tests
我想重构我在日常工作中经常使用的 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 root 执行所有测试
$cd myapp
$python -m unittest discover tests #same problem as above!
所以,问题出在simple_example.py和test_bar.py中的导入语句。
修复这些导入的最佳方法是什么?
请注意,我想使用 python 标准库 unittest 进行单元测试。
谢谢
查理
当 运行ning 测试代码时,您想进行绝对导入。这是因为当你 运行 进行单元测试等时,你应该假设你的 'library' 是安装在本地开发模式下进行测试的——不要使用相对导入,因为你不在相同的包裹。
以下是在 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 您的包是如何构建/创建的,并将在本地安装它以便您可以 运行 测试/ 搞砸了。
我想重构我在日常工作中经常使用的 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 root 执行所有测试
$cd myapp
$python -m unittest discover tests #same problem as above!
所以,问题出在simple_example.py和test_bar.py中的导入语句。 修复这些导入的最佳方法是什么?
请注意,我想使用 python 标准库 unittest 进行单元测试。
谢谢
查理
当 运行ning 测试代码时,您想进行绝对导入。这是因为当你 运行 进行单元测试等时,你应该假设你的 'library' 是安装在本地开发模式下进行测试的——不要使用相对导入,因为你不在相同的包裹。
以下是在 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 您的包是如何构建/创建的,并将在本地安装它以便您可以 运行 测试/ 搞砸了。