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

问题描述 投票:0回答:2

请假设以下项目结构:

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

我想从模块

fileChecker.py
内访问模块
fileHash.py
。 这是某种全局包。

一种方法是将路径附加到

sys.path
。 [顺便问一下,这是 PYTHONPATH 吗?]

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

  • 和上面一样吗? --> 但是可能存在指向模块的路径
    PYTHONPATH
    同名?
  • 所有工作都由
    setuptools
    完成吗?

我怎样才能以一种漂亮、干净的方式实现它?

非常感谢。


更新:

另请参阅下面我的回答 --> 当直接从其包目录中调用

fileHash.py
(包括像从文件
import fileChecker
那样导入)时,需要将项目的路径添加到
sys.path
如下所述)。

当从

/test 内部调用时,位于 sys.path

 内的
测试用例
(参见上面的结构)也需要添加到
/test
的路径。

python python-import
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
投票

我终于找到了另一个解决方案,非常直观,没有系统路径或任何需要的东西: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='[email protected]',
license='MIT',
packages=['files', 'hasher'], ## here the names
zip_safe=False)
© www.soinside.com 2019 - 2024. All rights reserved.