Подтвердить что ты не робот

Импорт модулей 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
4b9b3361

Ответ 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. Если вы хотите посмотреть образец производства, пожалуйста, оставьте комментарий по этой теме, чтобы опубликовать его позже.

С уважением.