提问者:小点点

Python包内导入模块的最佳实践


我有点困惑(实际上很多)与Python包装路径系统。

我有这个项目:

myproject/
    package1/
       setup.py
       src/
          __init__.py
          module1.py
          module2.py
          module3.py
       tests/
          __init__.py
          test_package1.py

    package2/
       setup.py
       src/
          __init__.py
          module1.py
          module2.py
          module3.py
       tests/
          test_package2.py

    package3/
       setup.py
       src/
          __init__.py
          module1.py
          module2.py
          module3.py
       tests/
          test_package3.py

这些包应该在CI过程后发布在私有存储库中(如果测试通过)。

重要提示:Package1使用package2,而package2使用package3。

所以package1的setup.py看起来像这样:

setuptools.setup(
    name='package1',
    version='1.4.0.dev1',
    install_requires=['setuptools~=50.3.2',
                      'boto3~=1.17.0',
                      'pandas~=1.3.4',
                      'package2~=1.4.0.dev1'],
    package_dir={"package1": "src"},
    packages=["package1"],
    include_package_data=True,
    setup_requires=['pytest-runner'],
    tests_require=['pytest'],
    python_requires=">=3.6"
)

package2的setup.py如下所示:

setuptools.setup(
    name='package2',
    version='1.4.0.dev1',
    install_requires=['PyYAML~=5.3.1'
                      'package3~=1.4.0.dev1'],
    package_dir={"package2": "src"},
    packages=["package2"],
    include_package_data=True,
    setup_requires=['pytest-runner'],
    tests_require=['pytest'],
    python_requires=">=3.6"
)

CI流程:

  1. 我正在运行pip install.每个包(来自相应的包目录)
  2. 从package3目录运行测试:python-m pytest测试-vvv
  3. 从package2目录运行测试:python-m pytest测试-vvv
  4. 从package1目录运行测试:python-m pytest测试-vvv

package2和package3的测试成功通过,但最后一步-在运行pytest for package1时,它会抱怨package2中的ModuleNotFoundError

module1.py(包装2):

from module2 import AwsService
...

AwsService只是在module2.py中定义的一个类。

我将导入更改为:from. import AwsService,重新安装包并重新运行package1测试。这次pytest抱怨package3中的import:

module1.py(包装3):

import module2
...

所以我将导入更改为。import module2并开始运行测试。

但是在package2的module3中,我有from module2 import AwsService,它是可以的,所以我怎么知道什么时候我必须做相对导入,什么时候不做?!。

我对所有这些路径行为都感到困惑。

也许我的setup.py不好,或者项目结构不好,或者我测试它的方式不好?


共1个答案

匿名用户

我的问题的解决方案只是将myproject的路径分配给PYTHONPATH:

export PYTHONPATH=/Users/yuri/projects/myproject/

当您通过pip install.在本地安装软件包并执行pip冻结时,您将看到您的软件包已安装,但您还将看到软件包附近的路径,路径如下:文件:///用户/yuri/项目/myproject/package1作为对原始位置的引用,Python看不到它。所以你必须手动添加路径。