Как добавить модуль Python в syspath?


69

У меня есть такая структура файлов:

Folder
   Common
      foo1.py
   TestFolder
      foo2.py

Я хочу импортировать в foo2.py и foo1.py. Я пытался, но это не работает на Ubuntu:

sys.path.append(os.path.abspath('../../'))
from Common import foo1.py

У вас есть __init__.pyфайл в вашей папке? Вот как Python создает пакеты и позволяет вам импортировать модули из этого пакета. guide.python-distribute.org/creation.html
Брайан,

У меня есть файл init.py в общем и в TestFolder
user284474

вам нужно это в каталоге папок, а также в подпапках, если вы хотите импортировать
Брайан

Этот init .py пуст?
user284474

1
да, это может быть пустым. Если вам не нужна определенная конфигурация для вашего пакета, но вам должно быть хорошо, если он пуст
Брайан,

Ответы:


115

Как python находит свои модули

Строго говоря, модуль - это отдельный файл Python, а пакет - это папка, содержащая файлы Python, сопровождаемые (может быть пустым) именем файла __init__.py, чтобы сообщить Python, что это пакет для импорта модулей. В обоих случаях модули нуждаются в .pyрасширении, но их импорт выполняется без (см. Далее ниже).

По умолчанию Python ищет свои модули и пакеты в $PYTHONPATH.

Чтобы узнать, что входит в $ PYTHONPATH, запустите следующий код в python (3):

import sys
print(sys.path)

Как добавить каталог

Время от времени

Из файла python вы можете время от времени добавлять пути к пути по умолчанию, добавляя следующие строки в раздел head вашего приложения или скрипта python:

import sys
sys.path.insert(0, "/path/to/your/package_or_module")

Например:

если у меня есть папка: /home/myname/pythonfilesи я хочу импортировать файл module_1.py, расположенный в этом каталоге, я добавляю это в раздел head моего кода:

import sys
sys.path.insert(0, "/home/myname/pythonfiles")

И я могу просто импортировать файл module_1.py:

import module_1

Когда я создаю пакет и хочу импортировать модуль (и) из пакета, мне нужно создать папку $PYTHONPATH, содержащую модули и сопровождаемый (может быть пустым) файлом, который называется__init__.py

Например:

Для того, чтобы импортировать из пакета (папка) называется my_packageв /home/myname/pythonfiles, добавьте /home/myname/pythonfilesпуть к вашему $PYTHONPATH, как и в примере 1, и импортировать модуль с именем module_2.py(в папке пакета) просто с: `

from <packagename> import module_2

Добавление каталогов на $PYTHONPATHпостоянной основе:

Добавьте следующую строку в ваш ~/.profileфайл.

export PYTHONPATH=$PYTHONPATH:/path/you/want/to/add

Подкаталоги

Изнутри пакета подкаталоги не включаются просто так; вам нужно «связать» каталоги. Чтобы импортировать модуль module_3.py, внутри папки subfolderвнутри папки packagename:

import packagename.subfolder.module_3

Учитывая тот факт, что все подпапки в пакете содержат собственный __init__.pyфайл.

Когда модуль находится в том же каталоге, что и скрипт или приложение

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

Пример:

Если у меня есть папка, содержащая script.pyи module.py, я могу просто импортировать модуль:

import module

Я также хотел бы предложить прочитать python.org/dev/peps/pep-0328 , особенно если вы нацелены на Python 3 (или планируете нацеливаться в будущем)
zaadeh

Почему printenv PYTHONPATHничего?
Стиви Дж

1
sys.path.append("/path/to/your/package_or_module")также добавляет путь к значению по умолчанию, и это менее запутанно. По сравнению с sys.path.insert(0,...)которым имеет 0в качестве первого аргумента.
Поль Ружье,

1
@PaulRougieux: проблема с добавлением пути заключается в том, что ваш модуль может уже существовать в другом месте пути (например, в файле .egg), и вы выберете ту версию вашего модуля вместо той, которая находится в вашем файле.
snark

6

Правильный способ использования относительного импорта:

from ..Common import foo1

И вам также нужно __init__.pyво всех ваших папках.


1
Спасибо. Но если у меня есть модуль, который состоит из двух папок Up, как я могу импортировать это? из .... Папка не работает
user284474

Работает ли с одним уровнем?
Сильвен Пино

С одним уровнем это работает.
user284474

хорошо, не могли бы вы принять этот ответ? для многоуровневого, хотя вы могли бы задать другой вопрос, но сначала взгляните на этот вопрос и этот ответ, чтобы узнать, как лучше всего вызвать ваши модули внутри пакета
Сильвен Пино,

Это правда для Python 2 или Python 3? Или оба?
alex

2

NB: Этот ответ устарел для последней версии Python 3, но здесь для более ранней версии. Для получения дополнительной информации читайте комментарии и https://www.python.org/dev/peps/pep-0420/


По сути, каждая папка с кодом Python, который вы хотите добавить в syspath, нуждается в файле __init__.py. Эти __init__.py файлы могут быть пустыми.


Насколько я понимаю, это уже не так, каталог теперь становится «пространством имен».
Аарон Холл

@ Аарон, интересно, источник?
don.joey

1
Попробуйте это для доказательства: python -c "from pathlib import Path; Path('ns').mkdir(); Path('ns/mod.py').write_text('''print('mod.py')'''); import ns.mod; from shutil import rmtree; rmtree('ns')"также вот некоторая соответствующая документация, PEP 420, которая описывает добавление семантики пакета пространства имен
Аарон Холл
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.