重构python模块配置以避免相对导入

时间:2008-12-06 01:57:34

标签: python configuration module

这与我的previous question有关。

我了解如何存储和读取配置文件。有ConfigParserConfigObj等选项。

对于假设的“蛋”模块,请考虑这种结构:

eggs/
  common/
    __init__.py
    config.py
  foo/
    __init__.py
    a.py

'eggs.foo.a'需要一些配置信息。我目前正在做的是'a',

import eggs.common.config
。这样做的一个问题是,如果'a'被移动到模块树中的更深层次,则相对导入会中断。绝对导入没有,但它们需要你的模块在你的PYTHONPATH上。

上述绝对导入的可能替代方法是相对导入。因此,在'a',

import .common.config

在不讨论相对绝对进口的优点的情况下,我想知道其他可能的解决方案吗?

edit-删除了VCS上下文

5 个答案:

答案 0 :(得分:2)

“导入......要求你的模块在你的PYTHONPATH上”

右。

那么,设置PYTHONPATH有什么问题?

答案 1 :(得分:0)

要求来自pkg_resources的陈述或许你需要的陈述。

答案 2 :(得分:0)

正如我从此以及之前的问题中所理解的那样,您只需要一条路径就可以进入sys.path。如果我们在谈论git作为VCS(在前一个问题中提到)时,任何时候只签出一个分支(单个工作目录)。您可以根据需要随时切换,合并分支。

答案 3 :(得分:0)

我正在考虑采用更“基于推送”的解决方案。不是导入共享对象(无论是用于配置还是某种类型的实用程序功能),而是让顶级 init 导出它,并且每个中间 init 从中导入它上面的图层,并立即重新导出它。

我不确定我是否有正确的python术语,如果我错了请纠正我。

像这样,任何需要使用共享对象的模块(在此示例的上下文中表示配置信息)只是从 init 中导入它自己的级别。

这听起来合理/可行吗?

答案 4 :(得分:0)

您可以通过将每个子目录添加到egg/__init__.py来欺骗导入机制:

__path__.append(__path__[0]+"\\common")
__path__.append(__path__[0]+"\\foo")

然后,您只需从egg命名空间导入所有模块;例如import egg.bar(如果你有文件egg / foo / bar.py) 请注意,foo和common不应该是一个包 - 换句话说,它们不应该包含__init__.py文件。

此解决方案完全解决了最终移动文件的问题;但是它会使名称空间变得平坦,因此它可能不会那么好,特别是在大项目中 - 个人而言,我更喜欢全名解析。