【问题标题】:Tests and python package structure测试和python包结构
【发布时间】:2011-03-05 18:22:37
【问题描述】:

我在构建我的 python 项目时遇到了一些问题。目前它是同一个文件夹中的一堆文件。我试图像这样构造它

proj/
  __init__.py
  foo.py
  ...
  bar/
    __init__.py
    foobar.py
    ...
  tests/
    foo_test.py
    foobar_test.py
    ...

问题是我无法从内部目录导入外部目录中的模块。这对测试来说尤其烦人。

我已阅读 PEP 328 关于相对导入和 PEP 366 关于从主模块的相对导入。但是这两种方法都要求基本包在我的 PYTHONPATH 中。确实我收到以下错误

ValueError: 尝试在非包中进行相对导入。

所以我在测试文件的顶部添加了以下样板代码

import os, sys
sys.path.append(os.path.join(os.getcwd(), os.path.pardir))

我仍然得到同样的错误。正确的方法是什么

  • 构建一个包,完成测试,并
  • 将基目录添加到路径以允许导入?

编辑根据评论中的要求,我添加了一个失败的示例导入(在文件 foo_test.py 中)

import os, sys
sys.path.append(os.path.join(os.getcwd(), os.path.pardir))
from ..foo import Foo

【问题讨论】:

  • 你能展示一个失败的导入示例吗?
  • 另外,请包含您的PYTHONPATH的值
  • echo $PYTHONPATH 现在是空的。

标签: python package


【解决方案1】:

当您使用-m 开关运行代码时,当前目录被添加到sys.path。因此,运行测试的最简单方法是从 proj 的父目录,使用以下命令:

python -m proj.tests.foo_test

要实现这一点,您需要在测试目录中包含一个__init__.py 文件,以便将测试正确识别为包的一部分。

【讨论】:

  • 谢谢!所以我缺少的是tests 本身应该是一个包。这是一个相当愚蠢的错误,但我无法弄清楚。
【解决方案2】:

我喜欢尽可能使用完整的 proj.NAME 包前缀导入模块。这是Google Python styleguide 推荐的方法。

让您保持包结构、使用完整包路径并继续进行开发的一种选择是使用 virtualenv 并将您的项目置于开发模式。您的项目的setup.py 需要使用setuptools 而不是distutils,以获取develop 命令。

这会让你避免上面提到的sys.path.append

% virtualenv ~/virt
% . ~/virt/bin/activate
(virt)~% cd ~/myproject
(virt)~/myproject% python setup.py develop
(virt)~/myproject% python tests/foo_test.py

foo_test.py 使用的地方:

from proj.foo import Foo

现在,当您在 virtualenv 中运行 python 时,您的 PYTHONPATH 将指向您项目中的所有包。您可以创建一个较短的 shell 别名来进入您的 virtualenv,而不必每次都输入 . ~/virt/bin/activate

【讨论】:

  • 看起来很有趣。我将不得不调查这个 virtualenv 工具。它是否允许我在可以访问当前目录作为包的虚拟环境中工作?或者它只是一个带有隔离 python 发行版的工具 - 更像是一个 chroot - 我必须在每次使用它之前安装我的包?
  • 这是一种创建隔离 Python 环境的快速方法,您可以快速删除并重新创建该环境。非常适合使用 pip/easy_install 试用模块,而不会污染系统 Python。 virtualenv activate 脚本将~/virt/bin 目录插入到PATH 的前面,以便在系统python 之前找到~/virt/bin/pythondevelop 命令使用.pth 文件将项目的包链接到~/virt/lib/pythonx.x/site-packages。它还修改了PS1 提示,让你知道你在 virtualenv 的“内部”。
  • 好建议,尽管这些天您可能希望选择distribute 作为setuptools 的更积极维护的替代方案。
  • 同意,setuptools 的使用范围更广,但人们应该转向兼容并积极维护的distribute
猜你喜欢
  • 2022-11-08
  • 2011-09-04
  • 2017-12-01
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
相关资源
最近更新 更多