运行 setuptools 测试时访问包的 `__init__.py` 中定义的名称
我已经开始将模块代码直接放入包 __init__.py
中,即使对于最终成为唯一文件的简单包也是如此。
所以我有一堆看起来像这样的包(尽管它们并不都被称为pants
:)
+ pants/
\-- __init__.py
\-- setup.py
\-- README.txt
\--+ test/
\-- __init__.py
我开始这样做是因为它允许我将代码放在一个单独的(并且,关键是,单独的) versionable)目录,并使其以与包位于单个 module.py
中相同的方式工作。我将它们保存在我的 dev python lib 目录中,在处理这些事情时我已将其添加到 $PYTHONPATH
中。每个包都是一个单独的 git 存储库。
编辑...
与典型的 Python 包布局相比,如 Radomir 的 答案,此设置使我不必将每个包的目录添加到我的 PYTHONPATH 中。
.../edit
这已经很好地解决了,但是我遇到了这个(有点晦涩)的问题:
当从包目录中运行测试时,包本身,即 __init__.py 中的代码>,不保证位于 sys.path
上。在我的典型环境下这不是问题,但如果有人下载 pants-4.6.tgz
并提取源代码发行版的 tarball,cd
进入该目录,然后运行python setup.py test
,包 pants
本身通常不会位于其 sys.path
中。
我觉得这很奇怪,因为我希望 setuptools 从被测包的父目录运行测试。然而,无论出于何种原因,它都不会这样做,我想是因为通常你不会以这种方式打包东西。
相对导入不起作用,因为 test
是一个顶级包,已被发现为 sys.path
当前目录组件的子目录。
我希望避免将代码移动到单独的文件中并将其公共名称导入到 __init__.py
中。主要是因为对于一个简单的模块来说,这似乎是毫无意义的混乱。
我可以从 setup.py
中将父目录显式添加到 sys.path
,但我不想这样做。一方面,至少在理论上,这可能会失败,例如,如果有人决定从其文件系统的根目录(可能是 Windows 驱动器)运行测试。但大多数情况下,它给人的感觉是偷工减料。
有更好的办法吗?
将代码放入 __init__.py
中是否被认为是特别糟糕的形式?
I've taken to putting module code directly in a packages __init__.py
, even for simple packages where this ends up being the only file.
So I have a bunch of packages that look like this (though they're not all called pants
:)
+ pants/
\-- __init__.py
\-- setup.py
\-- README.txt
\--+ test/
\-- __init__.py
I started doing this because it allows me to put the code in a separate (and, critically, separately versionable) directory, and have it work in the same way as it would if the package were located in a single module.py
. I keep these in my dev python lib directory, which I have added into $PYTHONPATH
when working on such things. Each package is a separate git repo.
edit...
Compared to the typical Python package layout, as exemplified in Radomir's answer, this setup saves me from having to add each package's directory into my PYTHONPATH.
.../edit
This has worked out pretty well, but I've hit upon this (somewhat obscure) issue:
When running tests from within the package directory, the package itself, i.e. code in __init__.py
, is not guaranteed to be on the sys.path
. This is not a problem under my typical environment, but if someone downloads pants-4.6.tgz
and extracts a tarball of the source distribution, cd
s into the directory, and runs python setup.py test
, the package pants
itself won't normally be in their sys.path
.
I find this strange, because I would expect setuptools
to run the tests from a parent directory of the package under test. However, for whatever reason, it doesn't do that, I guess because normally you wouldn't package things this way.
Relative imports don't work because test
is a top-level package, having been found as a subdirectory of the current-directory component of sys.path
.
I'd like to avoid having to move the code into a separate file and importing its public names into __init__.py
. Mostly because that seems like pointless clutter for a simple module.
I could explicitly add the parent directory to sys.path
from within setup.py
, but would prefer not to. For one thing, this could, at least in theory, fail, e.g. if somebody decides to run the test from the root of their filesystem (presumably a Windows drive). But mostly it just feels jerry-rigged.
Is there a better way?
Is it considered particularly bad form to put code in __init__.py
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为打包 python 程序的标准方法更像是这样:
然后你就避免了这个问题。
I think the standard way to package python programs would be more like this:
Then you avoid the problem.