具有相同结构的两个 python 个包使用了来自其他包的同名函数

Two python packages with the same structure use function of the same name from other package

我创建了 2 个包,分别命名为 A 和 B。这两个包具有相同的结构,因为它们做的事情非常相似,例如它们的结构如下所示:

A/
  __init__.py
  subpackage1/
    __init__.py
    submodule1.py
  subpackage2/
    __init__.py
    submodule2.py
  setup.py
  README.md
  requirements.txt

它们共享相同的子包、子模块和函数名称。每个模块都有一个 main 函数,它为我做 argparsing 并用这些参数调用一个函数。在我的 setup.py 中,我指定了额外的入口点,以便我可以从命令行调用模块:

import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

with open('requirements.txt') as f:
    requirements = f.readlines() 

setuptools.setup(
    name="A",
    version="0.0.1",
    author="Me",
    author_email="me@myself.com",
    description="Test package",
    long_description=long_description,
    long_description_content_type="text/markdown",
    packages=setuptools.find_packages(),
    entry_points ={
        'console_scripts': [
            'command1 = subpackage1.submodule1:main',
            'command2 = subpackage2.submodule2:main'
        ]
    },
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
    install_requires = requirements
)

当我在空白 docker 容器中安装包时,它工作正常,我可以从命令行使用 'command1' 和 'command2' 调用我的函数。

如前所述,包 B 具有完全相同的 setup.py 文件,除了名称。如果我也安装它,包 A 现在使用包 B 的入口点而不是它自己的入口点。这意味着,我用正确的名称调用了函数,但是来自错误的包。

我想将它们并排放在我的 docker 容器中。我必须如何调整我的包裹,以便系统可以区分它们?

我通过 pip 从我生成的 wheels 安装了这些包。

第一印象,目录结构似乎不对:第一个危险信号是 __init__.pysetup.py 在同一目录中不应该存在,第二个危险信号是目录setup.py 旁边不能是 sub-packages,它们是 top-level 包 .

在您的示例中,top-level 包在项目 A 中是 subpackage1subpackage2,在项目 B 中也是如此。所以在这两种情况下,安装后可导入的项目是 import subpackage1import subpackage2。这也意味着当您安装 A,然后安装 B 时,B 的 top-level 包会覆盖之前作为 A 的一部分安装的包(因为它们具有完全相同的名称)。

您可能想要做的是在项目 Asetup.py 旁边添加一个目录 a,然后将 subpackageN__init__.py 进入那个 a 目录(在项目 B 中也是如此)。因此该目录结构如下所示:

A/
  a/
    __init__.py
    subpackage1/
      __init__.py
      submodule1.py
    subpackage2/
      __init__.py
      submodule2.py
  setup.py
  README.md
  requirements.txt

然后导入将如下所示:

import a.subpackage1
import b.subpackage1

from a import subpackage2 as subpackagea2
from b import subpackage2 as subpackageb2

以下 setup.py 文件应相应调整:

# ...

setuptools.setup(
    # ...
    entry_points ={
        'console_scripts': [
            'commanda1 = a.subpackage1.submodule1:main',
            'commanda2 = a.subpackage2.submodule2:main'
        ]
    },
)