【发布时间】: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