【发布时间】:2010-09-26 00:16:53
【问题描述】:
我已经将模块代码直接放在包 __init__.py 中,即使对于最终成为唯一文件的简单包也是如此。
所以我有一堆看起来像这样的包(尽管它们并不全称为pants:)
+ pants/
\-- __init__.py
\-- setup.py
\-- README.txt
\--+ test/
\-- __init__.py
我开始这样做是因为它允许我将代码放在一个单独的(并且至关重要的是,单独的版本化)目录中,并让它以与包位于单个 module.py 中时相同的方式工作.我将这些保存在我的 dev python lib 目录中,我在处理此类事情时已将其添加到 $PYTHONPATH 中。每个包都是一个单独的 git repo。
编辑...
与典型的 Python 包布局相比,如 Radomir 的 answer 所示,这种设置使我不必将每个包的目录添加到我的 PYTHONPATH 中。
.../编辑
效果很好,但我遇到了这个(有点晦涩的)问题:
从包目录中运行测试时,包本身,即__init__.py 中的代码,不能保证在sys.path 上。这在我的典型环境下不是问题,但是如果有人下载pants-4.6.tgz并将源分发的tarball,cds 解压到目录中,然后运行python setup.py test,则包pants本身不会正常在他们的sys.path.
我觉得这很奇怪,因为我希望 setuptools 从被测包的父目录运行测试。但是,无论出于何种原因,它都不会那样做,我猜是因为通常你不会这样包装东西。
相对导入不起作用,因为test 是一个顶级包,被发现是sys.path 的当前目录组件的子目录。
我想避免将代码移动到单独的文件中并将其公共名称导入__init__.py。主要是因为对于一个简单的模块来说,这似乎是毫无意义的混乱。
我可以从setup.py 中将父目录显式添加到sys.path,但不希望这样做。一方面,至少在理论上,这可能会失败,例如如果有人决定从他们的文件系统(可能是 Windows 驱动器)的根目录运行测试。但大多数情况下,它只是感觉被操纵了。
有没有更好的办法?
将代码放在__init__.py 中是否被认为是特别糟糕的形式?
【问题讨论】:
标签: python testing module packages setuptools