在Python中从另一个包中导入包。

10
请假设以下项目结构:
/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目录中的测试用例也需要在从/test目录中调用时将该路径添加到sys.path中。

也许我应该补充一下,我尝试直接调用fileHash.py文件。调用mainProject.py没有问题。 - rocksteady
3
fileChecker.py 文件中:假设你使用绝对导入方式(Python 3.x 或 from __future__ import absolute_import),从 project.packages.hasher 模块中导入 fileHash 函数。 - mguijarr
2个回答

9

感谢mguijarr。

我在stackoverflow上找到了一个解决方案: 来源: 如何修复“尝试在非包中进行相对导入,即使存在__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,以便使codeship工作。

不过,在我看来,这似乎并不容易,我常常需要反思PYTHONPATH :)


0

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

然后按照他们在“全局安装包”中所解释的做法进行操作。

在您的情况下,将 "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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接