2017-03-13 45 views
3

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模块的一般情况,因为它们不驻留在同一个目录中。打包库时,我特意要求建议的方法。

有没有办法实现这一点,而无需修改路径?如果修改路径是唯一的方法,那么有没有办法以优雅的方式来完成?

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

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

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

+0

你的意思是除了在导入中使用相对路径或显式传递模块来导入?如果projectname是一个包,你可以随时在安装后直接导入它。在测试中,这通常是你做的。我在你的问题中遗漏了什么? – nir0s

+0

“在导入中使用相对路径还是显式传递模块导入”将如何工作?例如,“examples/helloworld.py''的输入行是什么?因为我一直无法做到这一点......至于另一个建议,Kenneth Reitz也提到了“期望将包装安装在网站包装中”作为替代方案,但是反对它。 –

+0

那我一定是误解了。你想从'examples'中导入某些东西?如果是这样,为什么它不是一个包? – nir0s

回答

1

虽然文件夹树看起来没问题,但我相信隐含地假设模块可用于导入是错误的,无论是从开发人员的角度来看,当然也从用户的角度来看。

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

用户安装软件包以使用它们很常见。有开发商一个明确的工作流程:

  1. 拥有画中画和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 [email protected]:nir0s/[email protected]#egg=distro 
packaging==16.8 
pyparsing==2.2.0 
six==1.10.0 

的包,被安装在编辑模式下,意味着有指向包的目录鸡蛋链接文件:

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

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

相关问题