Раскройте путь поиска Python для другого источника - PullRequest
77 голосов
/ 29 июня 2010

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

python someprojectfile.py

, я получаю

ImportError: no module named core.'somemodule'

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

TLDR:

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

Ответы [ 5 ]

142 голосов
/ 29 июня 2010

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

  • Задайте для переменной среды 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__))
11 голосов
/ 05 июля 2010

Вы также должны прочитать о пакетах 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

...

4 голосов
/ 11 октября 2017

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

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

from modules.report import report, reportError

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

python modules/report.py

Теперь Python жалуется, что не может найти «модуль под названием модули». Ключевым моментом здесь является то, что по умолчанию Python включает папку сценария в путь поиска, НО НЕ CWD. Так что эта ошибка на самом деле говорит: «Я не могу найти подпапку модулей». Это связано с тем, что в каталоге, в котором находится модуль report.py, нет подкаталога «modules».

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

import sys

sys.path.append(".")

Теперь Python ищет CWD (текущий каталог), находит подпапку «modules», и все хорошо.

2 голосов
/ 21 февраля 2015

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

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

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

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

import sys
for line in sys: print line

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

import mymodule

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

2 голосов
/ 06 апреля 2012

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

Поэтому я написал быстрое и грязное решение.Просто поместите это где-нибудь в свой sys.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
]

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

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