重构 python 模块配置以避免相对导入
Posted
技术标签:
【中文标题】重构 python 模块配置以避免相对导入【英文标题】:Refactoring python module configuration to avoid relative imports 【发布时间】:2010-09-25 15:15:12 【问题描述】:这与我的previous question 有关。
我了解如何存储和读取配置文件。有ConfigParser和ConfigObj等选择。
考虑这个结构作为假设的“eggs”模块:
蛋/ 常见的/ __init__.py 配置文件 富/ __init__.py 一个.py'eggs.foo.a' 需要一些配置信息。我目前正在做的是,在'a'中,
导入 egg.common.config。这样做的一个问题是,如果将“a”移动到模块树中的更深层次,则相对导入会中断。绝对导入不会,但它们要求您的模块位于 PYTHONPATH 上。
上述绝对导入的一个可能替代方案是相对导入。因此,在'a'中,
导入 .common.config
在不讨论相对导入与绝对导入的优点的情况下,我想知道其他可能的解决方案吗?
edit- 删除了 VCS 上下文
【问题讨论】:
相关问题:***.com/questions/171785/… 【参考方案1】:"imports ... 要求你的模块在你的 PYTHONPATH 上"
没错。
那么,设置PYTHONPATH
有什么问题?
【讨论】:
如果您同时有多个文件在开发中(例如多个分支),如果您每次都需要更改 PYTHONPATH,则很难从一个文件切换到另一个;另外,它添加了一个依赖项,需要一些工作才能受到版本控制。【参考方案2】:要求来自pkg_resources 的声明也许是你需要的。
【讨论】:
【参考方案3】:据我从这个问题和以前的问题中了解到,您只需要一条路径即可进入sys.path
。如果我们将 git
作为 VCS(在上一个问题中提到)在任何时候只检出一个分支(单个工作目录)。您可以随意切换、合并分支。
【讨论】:
我已经删除了 VCS 上下文,因为我意识到它与我的问题并不真正相关。切换 VCS 最终将这个特殊的设计问题暴露给我。【参考方案4】:我正在考虑一种更“基于推送”的解决方案。不要导入共享对象(无论是用于配置还是某种实用功能),让*** init 导出它,然后每个中间 init 导入它上面的图层,然后立即重新导出它。
我不确定我的 python 术语是否正确,如果我错了,请纠正我。
像这样,任何需要使用共享对象(在本示例的上下文中表示配置信息)的模块只需从 init 在其自身级别导入它。
这听起来合理/可行吗?
【讨论】:
【参考方案5】:您可以通过将每个子目录添加到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
文件。
这个方案彻底解决了最终移动文件的问题;但是它会使命名空间变平,因此它可能不是那么好,尤其是在大型项目中 - 就个人而言,我更喜欢全名解析。
【讨论】:
以上是关于重构 python 模块配置以避免相对导入的主要内容,如果未能解决你的问题,请参考以下文章