Если я CreateUser.py
перейду в основной каталог user_management, я могу легко использовать: import Modules.LDAPManager
to import LDAPManager.py
--- это работает.
Пожалуйста, не надо . Таким образом, LDAPManager
модуль , используемый CreateUser
будет не быть таким же , как тот , импортированными с помощью другого импорта. Это может создать проблемы, если у вас есть какое-то глобальное состояние в модуле или во время травления / распаковки. Избегайте импорта, который работает только потому, что модуль находится в том же каталоге.
Когда у вас есть структура пакета, вы должны:
Использование относительного импорта, то есть если CreateUser.py
в Scripts/
:
from ..Modules import LDAPManager
Обратите внимание , что это было (обратите внимание на прошедшее время) обескуражен PEP 8 только потому , что старые версии питона не поддерживают их очень хорошо, но эта проблема была решена лет назад. Тока версия PEP 8 делает предложить их в качестве приемлемой альтернативы абсолютного импорта. Они мне действительно нравятся внутри упаковки.
Используйте абсолютный импорт, используя полное имя пакета ( CreateUser.py
in Scripts/
):
from user_management.Modules import LDAPManager
Чтобы второй работал, пакет user_management
должен быть установлен внутри PYTHONPATH
. Во время разработки вы можете настроить среду IDE так, чтобы это происходило, без необходимости вручную добавлять вызовы sys.path.append
куда-либо.
Также мне кажется странным, что Scripts/
это подпакет. Поскольку в реальной установке user_management
модуль будет установлен site-packages
в lib/
каталоге, который находится в каталоге (какой бы каталог ни использовался для установки библиотек в вашей ОС), а сценарии должны быть установлены в bin/
каталоге (в зависимости от того, какой каталог содержит исполняемые файлы для вашей ОС).
На самом деле я считаю, Script/
что не должно быть даже ниже user_management
. Он должен быть на том же уровне user_management
. Таким образом, вам не нужно использовать -m
, но вам просто нужно убедиться, что пакет можно найти (это опять же вопрос настройки IDE, правильной установки пакета или использования PYTHONPATH=. python Scripts/CreateUser.py
для запуска сценариев с правильным путем).
Таким образом, я бы использовал следующую иерархию :
user_management (package)
|
|------- __init__.py
|
|------- Modules/
| |
| |----- __init__.py
| |----- LDAPManager.py
| |----- PasswordManager.py
|
Scripts/ (*not* a package)
|
|----- CreateUser.py
|----- FindUser.py
Затем код CreateUser.py
и FindUser.py
должен использовать абсолютный импорт для импорта модулей:
from user_management.Modules import LDAPManager
Во время установки убедитесь, что он user_management
попадает PYTHONPATH
в каталог, а сценарии находятся внутри каталога для исполняемых файлов, чтобы они могли найти модули. Во время разработки вы либо полагаетесь на конфигурацию IDE, либо запускаете CreateUser.py
добавление Scripts/
родительского каталога в PYTHONPATH
(я имею в виду каталог, содержащий оба user_management
и Scripts
):
PYTHONPATH=/the/parent/directory python Scripts/CreateUser.py
Или вы можете изменить PYTHONPATH
глобально, чтобы вам не приходилось указывать это каждый раз. В ОС Unix (Linux, Mac OS X и т. Д.) Вы можете изменить один из сценариев оболочки, чтобы определить PYTHONPATH
внешнюю переменную, в Windows вам нужно изменить настройки переменных среды.
Добавление Я считаю, что если вы используете python2, лучше избегать неявного относительного импорта, указав:
from __future__ import absolute_import
в верхней части ваших модулей. Этот способ import X
всегда означает импорт модуля верхнего уровняX
и никогда не будет пытаться импортировать X.py
файл, который находится в том же каталоге (если этого каталога нет в каталоге PYTHONPATH
). Таким образом, единственный способ выполнить относительный импорт - использовать явный синтаксис ( from . import X
), который лучше ( явный лучше, чем неявный ).
Это гарантирует, что вы никогда не будете использовать «фиктивный» неявный относительный импорт, поскольку это вызовет ImportError
явный сигнал о том, что что-то не так. В противном случае вы можете использовать модуль, который не соответствует вашему мнению.
python -m user_management.Scripts.CreateUser