【问题标题】:Python project and package directories layoutPython项目和包目录布局
【发布时间】:2011-02-03 10:35:53
【问题描述】:

我在python中创建了一个项目,我很好奇包在python中是如何工作的。

这是我的目录布局:

top-level dir
  \ tests
    __init__.py 
  \ examples
    __init__.py
    example.py
module.py

我将如何在我的 example.py 模块中包含 module.py。我知道我可以将 PYTHONPATH 设置为顶级目录,但这似乎不是一个好的解决方案。这就是 pydev 解决这个问题的方法,但我想要一个不需要更新环境变量的解决方案。

我可以在 example.py 的顶部放一些东西来更新 sys.path,如下所示:

from os import path
import sys

sys.path.append( path.dirname(path.abspath(path.dirname(__file__))) )

我也不认为这是一个合适的解决方案。

我觉得我缺少 python 包的一些基本部分。我正在 python 2.6 上测试这个。如果需要进一步澄清,请告诉我。

【问题讨论】:

标签: python packages


【解决方案1】:

Python 包非常简单:包是 sys.path 中任何条目下的任何目录,其中包含 __init__.py 文件。但是,只有通过 import package.modulefrom package import module 等相对导入方式导入的模块才被认为是在包中。请注意,这意味着通常有人必须设置 sys.path 以包含您想要导入的任何包之上的目录,无论是通过PYTHONPATH 还是其他方式。

主要的问题是主模块(直接从命令行运行的模块)总是__main__,无论它们位于何处。因此,它们必须进行绝对导入,并且要么依赖于设置的 PYTHONPATH,要么依赖于自己的 munge sys.path。

在您的情况下,我建议您在设置正确路径后使用一个小的 Python 脚本来运行您的示例。假设你把它放在顶级目录中:

#!/usr/bin/env python
import sys
import os.path

sys.path.append(os.path.dirname(__file__))
example = __import__("examples", globals(), locals(), sys.argv[1])

那么你的例子可以做“导入模块”。

或者,如果module.py 也包含在一个包中,请将“顶级目录”的父级添加到 sys.path,然后在示例模块中使用from .. import module 语法。此外,将包装器中的第一个参数更改为 __import__ 为“tldname.examples”,其中 tldname 是您的顶级目录的名称。

如果您不想依赖“示例运行器”模块,则每个示例都需要 sys.path 样板文件,或者您需要 PYTHONPATH 设置。对不起。

【讨论】:

  • 太棒了。主要模块被特殊处理,不包括任何其他模块,这是让我以一种可移植的、好的方式来解决这个问题的提示。在现在的 main 方法中,我们始终将本地项目的顶级目录添加到 sys.path,其他一切都按预期工作。谢谢!
【解决方案2】:

【讨论】:

  • 在尝试时,我收到以下错误:ValueError: Attempted relative import in non-package.我在示例目录和父目录中有一个__init__.py
  • 如果你不在包中工作,那么是的,你应该设置 PYTHONPATH。
  • 我在一个包里工作。我在顶级目录和示例目录中都有__init__.py
  • 除非您的代码在作为“import examples.example”(或通过从包中的另一个此类模块的相对导入)导入的上下文中运行,否则 Python 不会将其视为在包裹。如果您直接运行示例,则必须设置 sys.path 并执行绝对导入。
猜你喜欢
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 2010-11-13
  • 2011-04-18
  • 2020-01-08
  • 2011-01-29
  • 2012-01-21
  • 2012-09-17
相关资源
最近更新 更多