Python - конфликт пространства имен при развертывании по двум разным путям - PullRequest
0 голосов
/ 17 мая 2019

У меня есть пространство имен верхнего уровня, работающее как пространство имен организации. Давайте назовем это myorg, где __init__.py выглядит так:

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

Это развертывается в /opt, где живет наш Python, вместе с некоторыми развитыми библиотеками python - скажем, mylib.

Так что на интерпретаторе Python2.7 это работает

>>> import myorg
>>> import myorg.mylib

Помимо библиотек, у нас есть некоторый клиентский код, который развертывается в другом месте системы, в /bb/bin. Например, для clientA я могу иметь:

>>> import sys
>>> sys.path.append('/bb/bin')
>>> import clientA

и это работает.

Однако из-за структуры нашего кода мы используем одно и то же пространство имен myorg - так что clientB также находится под myorg, а также есть /bb/bin/myorg/__init__.py с теми же константами, что и в /opt путь.

Вопрос:

почему это работает -

>>> import sys
>>> sys.path.append('/bb/bin')
>>> import myorg.clientB

но это не так:

>>> import myorg # import from /opt location
>>> import sys
>>> sys.path.append('/bb/bin')
>>> import myorg.clientB # it should find the module under myorg in /bb/bin
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named clientB

Это также не работает:

>>> import myorg.mylib
>>> import sys
>>> sys.path.insert(0,'/bb/bin') # Adding the /bb/bin path first
>>> import myorg.clientB
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named clientB

Итак, это похоже на пространство имен myorg, если оно импортируется из /opt, то оно всегда будет пытаться найти модули внизу.

Почему это? Может кто-нибудь объяснить, как решить эту проблему и почему это происходит?

Я также не понимаю, почему добавление /bb/bin к моему пути не заставляет его работать.

TL; DR

Мое предполагаемое поведение или то, на что я надеялся, это:

  • поиск в /opt/ для модуля
  • если не найден, переходите к другому /bb/bin

Это работает в первом случае, но кажется, что если myorg был импортирован из /opt, то он ищет только модули внутри.

1 Ответ

0 голосов
/ 17 мая 2019

Это потому, что «myorg» уже загружен - python загружает модули / пакеты только один раз.Если вы сначала загрузите myorg (из / opt) (или любой субмодуль, так как Python загрузит все «шаги» импорта), то любой myorg.something будет относиться к этому.

Можете ли вы попробовать import as? PEP, описывающий это .

Если я понимаю, как работает python, это должно работать:

import myorg as whateveryouwant # import from /opt location
import sys
sys.path.append('/bb/bin')
import myorg.clientB

РЕДАКТИРОВАТЬ: Заметил ваш комментарий, что это не такне работает: (

Вы также можете попробовать просто добавить /bb/bin/myorg и затем импортировать просто clientB вместо myorg.clientB. Это уродливо, но должно работать.

...