Импорт модулей Python из разных рабочих каталогов
У меня есть Python script, который использует встроенные модули, но также импортирует несколько настраиваемых модулей, которые существуют в том же каталоге, что и основной script.
Например, я бы назвал
python agent.py
и agent.py имеет несколько импортных значений, включая:
import checks
где проверки находятся в файле в том же каталоге, что и agent.py
agent/agent.py
agent/checks.py
Когда текущим рабочим каталогом является агент /, тогда все в порядке. Однако, если я вызываю agent.py из любого другого каталога, он явно не может импортировать checks.py и, следовательно, ошибки.
Как я могу гарантировать, что пользовательские модули могут быть импортированы независимо от того, откуда вызывается agent.py, например,
python /home/bob/scripts/agent/agent.py
Ответы
Ответ 1
На самом деле ваш пример работает, потому что checks.py находится в том же каталоге, что и agent.py, но скажите, что checks.py находится в предыдущем каталоге, например:
agent/agent.py
checks.py
Затем вы можете сделать следующее:
path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
if not path in sys.path:
sys.path.insert(1, path)
del path
Обратите внимание на использование __file__
.
Ответ 2
Вам не нужно возиться с sys.path. Чтобы процитировать из документов Python 2.6 для sys.path:
Как инициализировано при запуске программы, первый элемент этого списка, путь [0], это каталог, содержащий script, который использовался для вызывать интерпретатор Python. Если каталог script не является (например, если интерпретатор вызывается в интерактивном режиме или если script считывается со стандартного ввода), путь [0] - пустая строка, который направляет Python на поиск модулей в текущем каталоге. Обратите внимание, что каталог script вставлен перед записью вставленный в результате PYTHONPATH.
=== amod.py ===
def whoami():
return __file__
=== ascript.py ===
import sys
print "sys.argv", sys.argv
print "sys.path", sys.path
import amod
print "amod __file__", amod.whoami()
=== result of running ascript.py from afar ===
C:\somewhere_else>\python26\python \junk\timport\ascript.py
sys.argv ['\\junk\\timport\\ascript.py']
sys.path ['C:\\junk\\timport', 'C:\\WINDOWS\\system32\\python26.zip', SNIP]
amod __file__ C:\junk\timport\amod.py
и если он снова запустится, последняя строка, конечно, изменится на... amod.pyc. Это, похоже, не новинка, она работает с Python 2.1 и 1.5.2.
Отладочные подсказки для вас: попробуйте два простых файла, например, у меня есть. Попробуйте запустить Python с -v и -vv. Покажите нам результаты ваших неудачных тестов, включая полное отслеживание и сообщение об ошибке, и ваши два файла. Расскажите, на какой платформе вы работаете, и какую версию Python. Проверьте разрешения на файл checks.py. Есть ли checks.something_else, которые вызывают помехи?
Ответ 3
Вам нужно добавить путь к текущему исполняемому модулю в переменную sys.path. Поскольку вы вызывали его в командной строке, путь к script всегда будет находиться в sys.argv [0].
import sys
import os
sys.path.append(os.path.split(sys.argv[0])[0])
Теперь, когда импорт ищет модуль, он также будет искать в папке, где находится файл agent.py.
Ответ 4
Есть несколько способов добавить вещи к PYTHONPATH
.
Прочитайте http://docs.python.org/library/site.html
-
Задайте переменную окружения PYTHONPATH
до запуска script.
Вы можете сделать это python -m agent
для запуска agent.py
из PYTHONPATH
.
-
Создайте .pth
файлы в каталоге lib/site-packages
.
-
Установите модули в lib/site-packages
.
Ответ 5
Я думаю, вам стоит подумать о том, чтобы сделать каталог агента подходящим пакетом Python. Затем вы размещаете этот пакет в любом месте пути python, и вы можете импортировать проверки как
from agent import checks
См. http://docs.python.org/tutorial/modules.html
Ответ 6
Если вы знаете полный путь к check.py, используйте этот рецепт (http://code.activestate.com/recipes/159571/)
Если вы хотите добавить каталог в системный путь - этот рецепт (http://code.activestate.com/recipes/52662/). В этом случае я должен определить каталог приложения (sys.argv [0]) передать это значение функции AddSysPath. Если вы хотите посмотреть образец производства, пожалуйста, оставьте комментарий по этой теме, чтобы опубликовать его позже.
С уважением.