Два пакета Python с одинаковой структурой используют одноименную функцию из другого пакета.

Я создал 2 пакета с именами A и B. Оба пакета имеют одинаковую структуру, так как они делают очень похожие вещи, например. их структура выглядит следующим образом:

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

Они имеют одни и те же названия субпакетов, субмодулей и функций. У каждого модуля есть основная функция, которая анализирует аргументы за меня и вызывает функцию с этими параметрами. В моем 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="[email protected]",
    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
)

Когда я устанавливаю пакет в пустой контейнер докера, он работает нормально, и я могу вызывать свои функции с помощью «command1» и «command2» из командной строки.

Как было сказано ранее, пакет B имеет точно такой же файл setup.py, за исключением имени. Если я также установлю это, пакет A теперь будет использовать точки входа пакета B вместо своих собственных. То есть я вызываю функцию с правильным именем, но не из того пакета.

Я хочу, чтобы они были рядом в моем док-контейнере. Как мне настроить свои пакеты, чтобы система могла различать их?

Я установил пакеты через pip из сгенерированных мной колес.


person DocDriven    schedule 01.10.2020    source источник
comment
На первый взгляд, структура каталогов кажется неправильной: первый красный флажок заключается в том, что __init__.py не должно быть в том же каталоге, что и setup.py, второй красный флажок заключается в том, что каталоги, следующие за setup.py, не могут быть подпакетами< /i>, они должны быть пакетами верхнего уровня.   -  person sinoroc    schedule 01.10.2020
comment
@sinoroc Я удалил верхний уровень __init__.py (который я фактически добавил из-за разочарования незадолго до публикации tbh). Тот же результат, что и раньше. Спасибо за уточнение терминологии!   -  person DocDriven    schedule 01.10.2020


Ответы (1)


На первый взгляд, структура каталогов кажется неправильной: первый красный флажок заключается в том, что __init__.py не должно быть в том же каталоге, что и setup.py, второй красный флажок заключается в том, что каталоги, следующие за setup.py, не могут быть подпакетами< /em>, это пакеты верхнего уровня.

В вашем примере пакеты верхнего уровня subpackage1 и subpackage2 в проекте A, а также в проекте B. Таким образом, в обоих случаях после установки импортируемыми элементами являются import subpackage1 и import subpackage2. Это также означает, что когда вы устанавливаете A, а затем B, пакеты верхнего уровня B перезаписывают те, которые были ранее установлены как часть A (поскольку они имеют точно такое же имя).

Что вы, вероятно, захотите сделать, так это добавить каталог a в проект A рядом с его setup.py и переместить как 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'
        ]
    },
)
person sinoroc    schedule 01.10.2020
comment
Это решило мою проблему. По какой-то причине я полностью упустил этот вариант при проектировании упаковки. Спасибо! - person DocDriven; 02.10.2020