【问题标题】:Two python packages with the same structure use function of the same name from other package两个具有相同结构的python包使用来自其他包的同名函数
【发布时间】:2021-01-17 09:46:17
【问题描述】:

我创建了 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 从我生成的轮子中安装了软件包。

【问题讨论】:

  • 第一印象,目录结构好像不对:第一个红旗是__init__.pysetup.py在同一目录下不应该有__init__.py,第二个红旗是下一个目录到setup.py 不能是子包,它们应该是顶级包
  • @sinoroc 我删除了顶级__init__.py(实际上是在发布tbh 前不久我出于沮丧而添加的)。结果和以前一样。感谢您澄清术语!

标签: python python-3.x pip package python-packaging


【解决方案1】:

第一印象,目录结构好像不对:第一个红旗是setup.py在同一目录下不应该有__init__.py,第二个红旗是setup.py旁边的目录可以不是子包,它们是顶级包

在您的示例中,项目A 和项目B 中的顶级包是subpackage1subpackage2。所以在这两种情况下,安装后可导入的项目是import subpackage1import subpackage2。这也意味着,当您安装A,然后安装B 时,B 的顶级包会覆盖之前作为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'
        ]
    },
)

【讨论】:

  • 这解决了我的问题。出于某种原因,我在设计包装时完全错过了这个选项。谢谢!
猜你喜欢
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
  • 1970-01-01
  • 2018-01-14
  • 1970-01-01
相关资源
最近更新 更多