Разверните путь поиска Python к другому источнику


Я только что присоединился к проекту с довольно большой существующей базой кода. Мы разрабатываем в linux и не используем и IDE. Мы запускаем через командную строку. Я пытаюсь выяснить, как заставить python искать правильный путь при запуске модулей проекта. Например, когда я запускаю что-то вроде:

python someprojectfile.py

Я

ImportError: no module named core.'somemodule'

Я получаю это для всех моих импорт я предполагаю, что это проблема с путем.

TLDR:

как мне получить Python поиск ~/codez/project/ и все файлы и папки для файлов *.py во время операторов импорта.

5 69

5 ответов:

есть несколько возможных способов сделать это:

  • установите переменную окружения PYTHONPATH в разделенный двоеточием список каталогов для поиска импортированных модулей.
  • в вашей программе, используйте sys.path.append('/path/to/search') чтобы добавить имена каталогов, которые вы хотите, чтобы Python искал импортированные модули. sys.path это просто список каталогов, которые Python ищет каждый раз, когда его просят импортировать модуль, и вы можете изменить его по мере необходимости (хотя я бы не стал рекомендуем удалить любой из стандартных каталогов!). Любые каталоги, которые вы помещаете в переменную окружения PYTHONPATH будет вставить в sys.path когда Python запускается.
  • использовать site.addsitedir добавить каталог sys.path. Разница между этим и просто добавлением заключается в том, что при использовании addsitedir, он также ищет .pth файлы в этом каталоге и использует их для возможного добавления дополнительных каталогов в sys.path на основе содержимого файлов. Смотрите документация для более подробной информации.

какой из них вы хотите использовать, зависит от вашей ситуации. Помните, что когда вы распространяете свой проект другим пользователям, они обычно устанавливают его таким образом, что файлы кода Python будут автоматически обнаружены импортером Python (т. е. пакеты обычно устанавливаются в site-packages каталог), так что если вы возитесь с sys.path в коде, который может оказаться ненужным и даже может иметь негативные последствия, когда этот код выполняется другой компьютер. Для развития, я бы рискнул предположить, что параметр PYTHONPATH обычно это лучший способ пойти.

однако, когда вы используете что-то, что просто работает на вашем собственном компьютере (или когда у вас есть нестандартные настройки, например, иногда в рамках веб-приложений), это не совсем редкость, чтобы сделать что-то вроде

from os.path import dirname
sys.path.append(dirname(__file__))

вы также должны прочитать о пакетах python здесь:http://docs.python.org/tutorial/modules.html.

из вашего примера, я бы предположил, что у вас действительно есть пакет в ~/codez/project. Файл __init__.py в каталоге python каталог сопоставляется с пространством имен. Если все ваши подкаталоги имеют __init__.py файл, то вам нужно только добавить базовый каталог в ваш PYTHONPATH. Например:

PYTHONPATH=$PYTHONPATH:$HOME / adaifotis / project

в дополнение к тестированию переменной среды PYTHONPATH, как объясняет Дэвид, вы можете протестировать ее в python следующим образом:

$ python
>>> import project                      # should work if PYTHONPATH set
>>> import sys
>>> for line in sys.path: print line    # print current python path

...

Я прочитал этот вопрос в поисках ответа, и мне не понравился ни один из них.

поэтому я написал быстрое и грязное решение. Просто поставьте это где-нибудь в вашей системе.путь, и он добавит любой каталог под folder (из текущего рабочего каталога), или под abspath:

#using.py

import sys, os.path

def all_from(folder='', abspath=None):
    """add all dirs under `folder` to sys.path if any .py files are found.
    Use an abspath if you'd rather do it that way.

    Uses the current working directory as the location of using.py. 
    Keep in mind that os.walk goes *all the way* down the directory tree.
    With that, try not to use this on something too close to '/'

    """
    add = set(sys.path)
    if abspath is None:
        cwd = os.path.abspath(os.path.curdir)
        abspath = os.path.join(cwd, folder)
    for root, dirs, files in os.walk(abspath):
        for f in files:
            if f[-3:] in '.py':
                add.add(root)
                break
    for i in add: sys.path.append(i)

>>> import using, sys, pprint
>>> using.all_from('py') #if in ~, /home/user/py/
>>> pprint.pprint(sys.path)
[
#that was easy
]

и мне это нравится, потому что я могу иметь папку для некоторых случайных инструментов и не иметь их в составе пакетов или чего-то еще, и все же получить доступ к некоторым (или всем) из них в нескольких строках код.

самый простой способ, который я нахожу, это создать файл " any_name.pth "и поместите его в папку"\Lib\site-packages". Вы должны найти эту папку, куда установлен Python.

в этот файл поместите список каталогов, в которых вы хотите сохранить модули для импорта. Например, сделайте строку в этом файле следующим образом:

C:\Users\example...пример\

Вы сможете сказать, что это работает, запустив это в python:

import sys
for line in sys: print line

вы увидите каталог распечатан, среди прочего, откуда вы также можете импортировать. Теперь вы можете импортировать "mymodule.py" файл, который находится в этом каталоге так же легко, как:

import mymodule

это не будет импортировать вложенные папки. Для этого вы можете представить себе создание скрипта python для создания.PTH файл, содержащий все вложенные папки в папке, которую вы определяете. Возможно, он запустится при запуске.

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

в моем проекте у меня был основной скрипт в Родительском каталоге, и, чтобы дифференцировать модули, я поместил все вспомогательные модули в подпапку под названием "модули". В моем основном скрипте я импортирую эти модули следующим образом (для модуля под названием report.py):

from modules.report import report, reportError

если я называю мой основной скрипт, это работает. Тем не менее, я хотел проверить каждый модуль с помощью в том числе main() в каждом, и вызывая каждый непосредственно, как:

python modules/report.py

теперь Python жалуется, что он не может найти "модуль под названием модули". Ключ здесь заключается в том, что по умолчанию Python включает папку скрипта в свой путь поиска, но не CWD. Так что эта ошибка говорит, на самом деле, "я не могу найти подпапку модулей". Это потому, что нет подкаталога "модули" из каталога, где report.py модуль находится.

Я считаю, что самое замечательное решение для этого нужно добавить CWD в путь поиска Python, включив это вверху:

import sys

sys.path.append(".")

теперь и Python поиск в текущий рабочий каталог (текущий каталог), находит "модули" суб-папку, и все будет хорошо.