请假定以下项目结构:
/project
/packages
/files
__init__.py
fileChecker.py
/hasher
__init__.py
fileHash.py
mainProject.py
/test
我想从模块 fileHash.py 中访问模块 fileChecker.py。 这是某种全局包。
一种方法是将路径附加到 sys.path。 [顺便问一下,这是 PYTHONPATH 吗?]
分发项目时有什么解决方案?
- 和上面一样吗? --> 但是可能会有指向模块的路径 在 PYTHONPATH 中同名?
- setuptools 会做所有的工作吗?
我怎样才能以一种漂亮而干净的方式实现它?
非常感谢。
更新:
另请参阅下面我的回答 --> 当直接从其包目录中调用 fileHash.py(包括像 from files import fileChecker 这样的导入)时,需要将项目的路径添加到 sys.path(如下所述)。
测试用例 位于/test 中(见上面的结构)也需要添加到 sys.path 的路径,当从/test 中调用时。
最佳答案
谢谢 mguijarr。
我在 stackoverflow 上找到了一个解决方案: 来源: How to fix "Attempted relative import in non-package" even with __init__.py
当我在项目文件夹/project中时,我可以这样调用模块:
python -m packages.files.fileHash (no .py here, because it is a package)
这很好用。 在这种情况下,PYTHONPATH 是已知的,导入可以如下所示:
from packages.files import fileChecker
如果不是直接调用,而是从我的包目录/packages/hasher 中调用 --> 需要设置 PYTHONPATH:
if __package__ is None:
import sys
from os import path
sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
from packages.files import fileChecker
else:
from packages.files import fileChecker
这里对我来说重要的是,要包含的路径是项目路径。
上面的代码片段(最后一个)已经包含了描述这两种情况的案例(称为包和直接)。
非常感谢您的帮助。
更新:
- 只是为了让我的回答更完整
Python在做的时候自动将当前路径添加到PYTHONPATH
python fileHash.py
除了上述选项之外,另一种选项是在运行程序时像这样设置 PYTHONPATH
PYTHONPATH=/path/to/project python fileHash.py
我获得了一些经验,我想分享一下:
- 我不再从他们的目录中运行模块。
- 启动应用程序、运行测试或 sphinx 或 pylint 或任何在项目目录中完成的操作。
- 这可以确保项目目录包含在 python 路径中,并且可以找到所有包和模块,而无需在导入时执行其他操作。
- 我仍然使用 sys.path 将 python 路径设置为项目文件夹的唯一地方是在我的 setup.py 中,以便代码传输工作。
不过,在我看来,这在某种程度上并不是一件容易的事情,我发现自己经常反射(reflect) PYTHONPATH :)
关于python - 从python中的另一个包中导入一个包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33723812/