【问题标题】:How to include examples or test programs in a package?如何在包中包含示例或测试程序?
【发布时间】:2017-08-03 21:35:20
【问题描述】:

Python Cookbook 建议“典型库包”采用以下树形结构:

projectname/
    README.txt
    Doc/
        documentation.txt
    projectname/
        __init__.py
        foo.py
        bar.py
        utils/
            __init__.py
            spam.py
            grok.py
    examples/
        helloworld.py

您会注意到examples/ 不是实际包的一部分,它位于projectname/projectname/ 下(您可以在其中找到包的顶级__init__.py)。

嗯,examples/helloworld.py 显然需要导入 projectname 包。

我知道 StackOverflow 中至少有 2-3 个相关问题。我不认为这是重复的,因为其他问题要么涉及包内导入,要么涉及从另一个 python 模块导入一个 python 模块的一般情况,当它们不位于同一目录中时。我在打包库时特别要求建议的方法来执行此操作。

有没有办法在不修改路径的情况下实现这一点?如果修改路径是唯一的方法,有没有办法以优雅的方式完成?

让我详细说明最后一点。在 Kenneth Reitz 的 Repository Structure and Python 中,出现了类似的结构,使用 tests/ 而不是 examples/。这是完全相同的问题。他建议使用“一个简单(但显式)的路径修改来正确解析包。”好的,但这是实际代码:

import os
import sys
sys.path.insert(0, os.path.abspath('..'))

我真的不喜欢.. 部分。我希望有一个更通用的解决方案,希望它可以从我选择运行示例(或测试)的任何目录中工作。

【问题讨论】:

  • 您的意思不是在导入中使用相对路径或显式传递模块进行导入?如果 projectname 是一个包,您总是可以在安装后显式导入它。在测试中,这通常是你所做的。我在你的问题中遗漏了什么吗?
  • “在导入中使用相对路径或显式传递模块以导入”如何工作?例如,examples/helloworld.py 的导入行是什么?因为我无法让它工作......至于另一个建议,Kenneth Reitz 还提到“期望将包安装在站点包中”作为替代方案,但反对它。
  • 那我一定是误会了。你想从examples 导入一些东西吗?如果是这样,为什么不是一个包?
  • examples/helloworld.py 是如何使用 projectname 包的示例。所以,examples/helloworld.py 必须导入 projectname 包。不幸的是,examples/helloworld.py 开头的简单import projectname 将不起作用。相对导入也不会,如果我理解正确的话,它只适用于 within 某个包的导入。 examples/helloworld.py 在包外。
  • 这是很常见的事情。您使用 virtualenv 并以可编辑模式安装包(使用 pip),这样您就可以修改代码并立即执行它,而无需每次都安装。它比尝试导入东西更清晰和明确。如果您想进一步讨论,让我们将其移至聊天。

标签: python python-import python-packaging


【解决方案1】:

虽然文件夹树看起来不错,但我认为从开发人员的角度和用户的角度来看,隐含地假设模块可用于导入是错误的。

确实,您可以在技术上使用sys.path.insert(0, os.path.abspath('..')) 为 python 添加任何路径以允许从中导入,但这意味着您,开发人员,必须确保添加的路径始终位于正确的位置。

用户安装包来使用它们是很常见的。开发人员有一个清晰的工作流程:

  1. 已安装 pip 和 virtualenv(甚至更好的是 virtualenvwrapper)
  2. 使用 pip 的-e 标志以可编辑模式安装包,这意味着您对代码所做的任何更改都将直接影响执行。您无需在每次更改代码时都重新安装。
  3. 由于始终安装您的代码(具体而言,在 site-packages 下作为用户,但在开发时处于可编辑模式),您始终可以使用任何示例或测试中的明确名称导入包。

一个常见的工作流程:

$ pip install virtualenv
...
$ virtualenv distro
New python executable in /home/nir0s/work/distro/bin/python3
Also creating executable in /home/nir0s/work/distro/bin/python
Installing setuptools, pip, wheel...done.

$ source distro/bin/activate

# install in editable mode
$ pip install -e ~/repos/nir0s/distro/
Obtaining file:///home/nir0s/repos/nir0s/distro
Installing collected packages: distro
  Running setup.py develop for distro
Successfully installed distro

(distro) $ pip freeze
appdirs==1.4.3
-e git+git@github.com:nir0s/distro@e8a182f9d1dbe6391f25...#egg=distro
packaging==16.8
pyparsing==2.2.0
six==1.10.0

安装在可编辑模式下的包,意味着有一个指向包目录的egg-link文件:

$ cat distro/lib/python3.6/site-packages/distro.egg-link 
/home/nir0s/repos/nir0s/distro

用户会做同样的事情,而无需处理可编辑模式。只需创建虚拟环境并在其中安装软件包。然后,当他们完成工作时,他们将删除这些虚拟环境。轻松愉快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 2021-01-16
    相关资源
    最近更新 更多