【发布时间】:2014-07-18 13:18:54
【问题描述】:
我的目录结构如下:
some-tools-dir/
base_utils.py
other_utils.py
some-tool.py
some-other-tool.py
some-other-tools-dir/
basetools -> symlink to ../some-tools-dir
yet-another-tool.py
在other_utils.py,我有:
import base_utils
现在,在yet-another-tool.py,我想做:
import basetools.other_utils
这不起作用,因为 Python 无法将 basetools 识别为 Python 包。
所以我添加了一个空的basetools/__init__.py。
现在,在other_utils 中,我得到了异常:
import base_utils
ImportError: No module named base_utils
所以我把那行改成:
from . import base_utils
yet-another-tool.py 现在可以使用了。
但是,some-tool.py 不再起作用。它导入other_utils,我得到了异常:
from . import base_utils
ValueError: Attempted relative import in non-package
现在,我可以将这个 hack/workaround 添加到 some-tools-dir/*-tool.py:
import os, sys
__package__ = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
sys.path += [os.path.dirname(os.path.dirname(os.path.abspath(__file__)))]
__import__(__package__)
此外,使所有本地导入在这些文件中相对。
我想这解决了问题。但是,它看起来有些难看,我必须修改sys.path。我尝试了这个 hack 的几种变体,但是,如果可能的话,我想支持多个 Python 版本,所以使用模块 importlib 变得很复杂,尤其是。因为我有 Python 3.2,我不喜欢使用模块 imp,因为它已被弃用。而且,它似乎只会变得更加复杂。
我有什么遗漏吗?对于一个似乎并不罕见(对我来说)的用例来说,这一切看起来都很难看而且太复杂了。我的 hack 有更简洁/更简单的版本吗?
我愿意做的一个限制是只支持 Python >=3.2,如果这样可以简化任何事情的话。
【问题讨论】:
标签: python python-3.x python-import