У меня есть пространство имен верхнего уровня, работающее как пространство имен организации. Давайте назовем это 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
, то он ищет только модули внутри.