从 python 中的另一个包中导入包

importing a package from within another package in python

请假定以下项目结构:

/project
  /packages
    /files
      __init__.py
      fileChecker.py
    /hasher
      __init__.py
      fileHash.py
    mainProject.py
    /test

我想从模块 fileHash.py 中访问模块 fileChecker.py。 这是某种全局包。

一种方法是将路径附加到 sys.path。 [请问这是PYTHONPATH吗?]

分发项目时有什么解决方案?

我怎样才能以干净利落的方式实现它?

非常感谢。


更新:

另见下面我的回答 --> 当直接从其包目录中调用 fileHash.py(包括像 from files import fileChecker 这样的导入)时,需要将项目的路径添加到 sys.path( 如下所述).

位于 /test 中的测试用例(见上面的结构)也需要添加到 sys.path 的路径,当从 /test.

中调用时

谢谢 mguijarr。

我在 Whosebug 上找到了一个解决方案: 资源: 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

这里对我来说重要的是,要包含的路径是项目路径。

上面的代码片段(最后一个)已经包含了描述这两种情况的案例(称为包和直接)。

非常感谢您的帮助。

更新:

  1. 只是为了让我的回答更完整

Python 执行时自动将当前路径添加到 PYTHONPATH

python fileHash.py

除上述选项外,另一种选择是在 运行像这样运行程序时设置 PYTHONPATH

PYTHONPATH=/path/to/project python fileHash.py
  1. 积累了一些经验,分享一下:

    • 我不再 运行 目录中的模块。
    • 启动应用程序,运行测试或 sphinx 或 pylint 或任何都在项目目录中完成。
    • 这确保项目目录包含在 python 路径中,并且所有包、模块都可以找到,而无需对导入进行额外的操作。
    • 我仍然使用 sys.path 将 python 路径设置到项目文件夹的唯一地方是在我的 setup.py 中,以便代码传输工作。

不过,在我看来,这在某种程度上并不是一件容易的事情,我发现自己经常反映 PYTHONPATH :)

我终于找到了另一个解决方案,非常直观,不需要系统路径或任何需要的东西:https://www.tutorialsteacher.com/python/python-package

然后按照他们在“'Install a Package Globally'”中的说明进行操作。

在您的情况下,将“setup.py”文件放入包目录并添加两个包:

from setuptools import setup
setup(name='mypackage',
version='0.1',
description='Testing installation of Package',
url='#',
author='malhar',
author_email='mlathkar@gmail.com',
license='MIT',
packages=['files', 'hasher'], ## here the names
zip_safe=False)