我有以下目录结构:
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
中,我有:
现在,在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
现在,我可以将此破解/解决方法添加到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
。我尝试了这个方法的几个变体,但是,如果可能的话,我想支持多个Python版本,因此使用模块importlib
变得很复杂,特别是因为我有python3.2,而且我不喜欢使用模块imp
,因为它已经过时了。而且,这似乎只会变得更加复杂。在
我有什么遗漏吗?这一切看起来都很难看,而且对于一个并不罕见的用例来说太复杂了(对我来说)。我的黑客有更简洁的版本吗?在
我愿意做的一个限制是只支持Python>;=3.2,如果这简化了任何事情。在
(注意,这个答案是通过将this answer和this question的信息拼凑而成的,所以如果你喜欢的话,就去投票吧)
这看起来不那么老套,至少在Python2.7+中可以使用:
我认为你觉得这很困难的主要原因是在python包中包含可执行脚本实际上是不寻常的。Guido van Rossum实际上称之为"antipattern"。通常,您的可执行文件位于包的根目录之上,然后可以简单地使用:
^{pr2}$不用大惊小怪。在
或者,如果您想执行包中的脚本,您实际上将其作为包的一部分调用(同样,从包的父目录调用):
你能把顶端的根路径添加到PYTHONPATH中吗?在
如果是这样的话,您可以添加
文件到一些工具目录(和/或其他一些工具目录)
然后从另一个_实用工具.py你知道吗
^{pr2}$在另一个-工具.py你知道吗
然后可以删除符号链接,并使用适当的名称空间。在
相关问题 更多 >
编程相关推荐