Импорт модулей Python из другого рабочего каталога - PullRequest
30 голосов
/ 26 июня 2009

У меня есть скрипт Python, который использует встроенные модули, но также импортирует несколько пользовательских модулей, которые существуют в той же директории, что и основной скрипт.

Например, я бы назвал

python agent.py

и agent.py имеет несколько импортов, в том числе:

import checks

где проверки находятся в файле в том же каталоге, что и agent.py

agent/agent.py
agent/checks.py

Когда текущим рабочим каталогом является агент /, тогда все в порядке. Однако, если я вызываю agent.py из любого другого каталога, он, очевидно, не сможет импортировать check.py и другие ошибки.

Как я могу гарантировать, что пользовательские модули могут быть импортированы независимо от того, откуда вызывается agent.py, например,

python /home/bob/scripts/agent/agent.py

Ответы [ 7 ]

30 голосов
/ 26 июня 2009

На самом деле ваш пример работает, потому что check.py находится в том же каталоге, что и agent.py, но, скажем, check.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__.

12 голосов
/ 26 июня 2009

Вам НЕ нужно возиться с sys.path. Чтобы процитировать документы Python 2.6 для sys.path:

Как инициализируется при запуске программы, первый элемент этого списка, путь [0], каталог, содержащий скрипт, который использовался для вызвать интерпретатор Python. Если каталог сценария не доступны (например, если переводчик вызывается в интерактивном режиме или если скрипт читается из стандартного ввода), путь [0] является пустой строкой, который направляет Python для поиска модулей в текущем каталоге в первую очередь. Обратите внимание, что каталог скриптов вставляется перед записями вставлен в результате 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. Проверьте права доступа к файлу check.py. Есть checks.omething_else, который вызывает помехи?

7 голосов
/ 26 июня 2009

Вам необходимо добавить путь к исполняемому в данный момент модулю в переменную sys.path. Поскольку вы вызывали его в командной строке, путь к сценарию всегда будет в sys.argv [0].

import sys
import os
sys.path.append(os.path.split(sys.argv[0])[0])

Теперь, когда импорт ищет модуль, он также будет искать в папке, в которой находится файл agent.py.

5 голосов
/ 26 июня 2009

Есть несколько способов добавить вещи в PYTHONPATH.

Чтение http://docs.python.org/library/site.html

  1. Установите переменную среды PYTHONPATH перед запуском сценария.

    Вы можете сделать это python -m agent, чтобы запустить agent.py из вашего PYTHONPATH.

  2. Создание .pth файлов в каталоге lib/site-packages.

  3. Установите ваши модули в lib/site-packages.

1 голос
/ 29 января 2018

Чтобы обобщить мое понимание вашей цели, вы хотите иметь возможность импортировать пользовательские пакеты, используя import custom_package_name независимо от того, откуда вы вызываете python и где бы ни находился ваш скрипт python.

В ряде ответов упоминается то, что я собираюсь описать, но я чувствую, что большинство ответов предполагают много предыдущих знаний. Я постараюсь быть максимально откровенным.

Чтобы достичь цели, позволяющей импортировать пользовательские пакеты с помощью оператора import, их необходимо обнаружить где-то по пути, который Python использует для поиска пакетов. Python на самом деле использует несколько путей, но мы сосредоточимся только на том, который можно найти, комбинируя вывод sys.prefix (в вашем интерпретаторе python) с /lib/pythonX.Y/site-packages (или lib/site-packages, если вы используете windows), где XY - твоя версия на питоне.

Конкретно, найдите путь, который использует ваш питон, запустив:

import sys
your_path = sys.prefix + '/lib/pythonX.Y/site-packages'
print(your_path)

Этот путь должен выглядеть примерно так: /usr/local/lib/python3.5/site-packages, если вы используете Python 3.5, но он может сильно отличаться в зависимости от ваших настроек.

Python использует этот путь (и несколько других) для поиска пакетов, которые вы хотите импортировать. Итак, вы можете поместить свои пользовательские пакеты в папку /usr/local/lib/python3.5/site-packages. Не забудьте добавить в папку файл init .py.

Чтобы снова быть конкретным, в терминале:

cd your_path
cp path_to_custom_package/custom_package ./

Теперь вы сможете импортировать все свои собственные пакеты, как если бы пакет находился в одном каталоге (т. Е. import package.subpackage для каждого файла подпакета в вашем пакете должно работать).

1 голос
/ 06 июля 2009

Если вы знаете полный путь к check.py, используйте этот рецепт (http://code.activestate.com/recipes/159571/)

Если вы хотите добавить каталог в системный путь - этот рецепт (http://code.activestate.com/recipes/52662/). В этом случае мне нужно определить каталог приложения (sys.argv [0]) и передать это значение в функцию AddSysPath. Если вы хотите посмотреть образец продукции, пожалуйста, оставьте комментарий к этой теме, поэтому я опубликую его позже.

С уважением.

1 голос
/ 26 июня 2009

Я думаю, вам следует подумать о том, чтобы сделать каталог агента соответствующим пакетом Python. Затем вы помещаете этот пакет в любом месте пути Python, и вы можете импортировать чеки как

from agent import checks

См. http://docs.python.org/tutorial/modules.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...