我一直在尝试像这样的层次结构的各种用法以及绝对导入和相对导入之间的差异,并且无法弄清楚如何在没有简单的情况下对包,子包和模块执行常规操作把所有东西放在sys.path中。我有一个双级封装层次:在Python 3中测试子包模块
MyApp __init__.py Application __init__.py Module1 Module2 ... Domain __init__.py Module1 Module2 ... UI __init__.py Module1 Module2 ...
我希望能够做到以下几点:在一个模块的“如果主要”的模块导入时,从其他
- 运行测试代码模块在同一个目录中。
- 在每个子包中有一个或多个测试代码模块,用于对子包中的模块执行单元测试。
- 有一组单元测试,它们位于某个合理的位置,但位于子包之外,可以位于兄弟包,顶层包或顶层包之外(尽管所有这些最终都可能在运行在每个子包中的测试)
- 从三个子包级别中的任何一个“输入”结构,例如运行仅使用域模块的代码,运行仅使用应用程序模块的代码,但Application使用来自应用程序和域模块的代码,并且从GUI运行代码使用来自GUI和应用程序的代码;例如,应用程序测试代码将导入应用程序模块,但不导入域模块。
- 在没有子包的情况下开发大量代码之后,在将模块组织到此层次结构中之后继续开发和测试。
我知道如何使用相对导入,使得把MyApp的它的sys.path外部代码可以导入MyApp的,进口从他们的模块,它希望所有的子包,和进口的东西,而在各子包模块可以导入来自相同子包或兄弟包的其他模块。然而,上面列出的开发需求似乎与子包构造不兼容 - 换句话说,我不能用两种方法:一种从外部使用并且在内部使用的结构良好的多层包体系,特别是用于测试而且还因为来自一个设计级别(尤其是UI)的模块不应该从下一个设计级别的设计级别导入模块。
对不起长篇大论,但我认为它代表了许多人已经采用新的相对进口机制的斗争。
模块可以相对彼此引用之前,必须有绝对导入。 Application模块中的程序test.py不能从.module1中导入,也不能从..Domain.Module2中导入:我会得到“尝试在非包中导入相对”错误。我能做的最好的做法是让测试代码将'..'添加到sys.path中,并通过引用Application来完成它的导入。Module1等。在导入的应用程序中,Module1可以从.Module2导入。但是,这些都不能引用..domain.Module1。要做到这一点,test.py必须将../ ..放在路径上并从MyApp.Application导入。 – 2009-12-30 15:39:35
为什么你不想首先使用绝对导入?他们非常好。 – 2009-12-30 21:31:32
因为例如在开发过程中,我想快速测试一个子模块,所以我直接在子模块中进行测试。 不,相对导入不允许与绝对导入完全相同的东西:在子包中运行脚本,并且无法通过相对导入来访问顶层包。 – Turion 2012-02-11 23:29:06