Python установка коллизий имени пакета - PullRequest
1 голос
/ 24 марта 2020

У меня есть проект, который выглядит следующим образом:

.
├── A
│   ├── setup.py
│   ├── __init__.py
│   ├── a.py
│   └── data.py
└── B
    ├── b.py
    └── data.py

У меня нет контроля над A, но я бы хотел использовать его в B/b.py. Я не могу переписать любой код в папке A (кроме setup.py).

Я попробовал это:

# File A/setup.py
from setuptools import setup, find_packages
setup(name='packageA', version='1.0', packages=find_packages())

При следующей установке / тестах:

$ cd B
$ pip install -e ../A
$ python -c "import a; print(a)"
<module 'a' from 'A/a.py'>
$ python -c "import data; print(data)"
<module 'data' from 'B/data.py'> 
# How to get the same for <module 'data' from 'A/data.py'>?

Меня беспокоит столкновение имен, я хотел бы иметь возможность импортировать A/data.py и B/data.py в b.py. Я хотел знать, есть ли способ обойти это?

Я бы хотел написать что-то вроде:

$ python -c "from A import data; print(data)"
<module 'data' from 'A/data.py'>

Я пытался сделать setup.py на один уровень выше (в каталоге root), но если я это сделаю тогда у меня проблемы в A:

$ cd B
$ pip install -e ..
$ python -c "from A import data; print(data)"
Traceback (most recent call last):
  File "A/data.py", line 1, in <module>
    from a import some_function
ImportError: cannot import name 'some_function' from 'a' (unknown location)

Если бы я мог переписать A/data.py Я мог бы просто сделать это (но я не могу):

from A.a import some_function

Возможно ли это изменить setup.py для инкапсуляции A под (поддельным) именем модуля? Любое решение приветствуется.

1 Ответ

0 голосов
/ 24 марта 2020

Несколько возможных решений:

  1. Установите A как пакет. cd A && python3 setup.py install. Предположительно это устанавливаемый пакет. Теперь вы можете импортировать A, как вы обычно ожидаете.
  2. Добавьте A к PYTHONPATH. Это полезно, когда вы программируете на B, но вам нужна информация, извлеченная из A. Таким образом, вы можете изменить содержимое в A, например, отладочные сообщения, и при этом ваша программа будет работать. PYTHONPATH=/path/to/A python -c "import a; print(a)"
  3. Вы можете создать запуск программы из родительской папки, импортировать их как обычные модули. Удостоверьтесь, что вы используете относительный импорт .

$ cd B
$ pip install -e ../A
$ python -c "import a; print(a)"
<module 'a' from 'A/a.py'>
$ python -c "import data; print(data)"
<module 'data' from 'B/data.py'> 
# How to get the same for <module 'data' from 'A/data.py'>?

Меня беспокоит коллизия имен, я хотел бы иметь возможность импортировать оба A / data.py и B / data.py в b.py. Я хотел знать, есть ли способ обойти это?

Я хотел бы иметь возможность написать что-то вроде:

$ python -c "from A import data; print(data)"
<module 'data' from 'A/data.py'>

Вы делаете from A import data. Тогда у вас есть "A/data.py". В случае коллизий имен вы также можете сделать from a import data as newname.
Это предполагает, что у вас установлен A как модуль python. (Будь то setup.py install, pip install или добавление библиотеки к PYTHONPATH.)

...