sys.path Python
Введение | |
ModuleNotFoundError | |
Пример | |
Отдельные части | |
import | |
sys.path.append | |
PYTHONPATH | |
Похожие статьи |
Введение
Объект sys.path это
список
директорий.
Когда Python получает команду import, сперва он пытается найти нужный модуль в первой директории
из списка sys.path, затем во второй и так далее.
Как только находится совпадение поиск заканчивается.
Если у вас несколько модулей с одинаковым названием, найдётся тот, чья директория ближе к началу списка.
Не факт, что это будет нужный. Если кто-то вставит в начало вашего sys.path директорию с кучей
интересных модулей, выполняться будут именно они.
ImportError
Поднимается если была попытка импортировать несуществующий модуль
ModuleNotFoundError
Поднимается если была попытка импортировать несуществующий модуль
>>> import missing
Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'missing'
Пример
Перейдите в интерактивный режим
python
Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 22:45:29) [MSC v.1916 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>>
Выполните
import sys
И затем
sys.path
В Windows результат будет примерно таким (обратные слэши \)
['', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\python38.zip', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\DLLs', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\lib', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32', 'C:\\Users\\Andrei\\AppData\\Roaming\\Python\\Python38\\site-packages', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\lib\\site-packages']
В Linux таким (обычные слэши /)
['', '/home/andrei/.pyenv/versions/3.9.5/lib/python39.zip', '/home/andrei/.pyenv/versions/3.9.5/lib/python3.9', '/home/andrei/.pyenv/versions/3.9.5/lib/python3.9/lib-dynload', '/home/andrei/.local/lib/python3.9/site-packages', '/home/andrei/.pyenv/versions/3.9.5/lib/python3.9/site-packages']
Отдельные части
Так как sys.path это список никто не мешает нам обращаться к его частям или отедльным элементам
>>> import sys
>>> sys.path
['', 'C:\\Users\\Andrei\\python\\pluralsight\\packages\\not_searched', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\python38.zip', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\DLLs', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\lib', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32', 'C:\\Users\\Andrei\\AppData\\Roaming\\Python\\Python38\\site-packages', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\lib\\site-packages']
>>> sys.path[0]
''
>>> sys.path[-5:]
['C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\DLLs', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\lib', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32', 'C:\\Users\\Andrei\\AppData\\Roaming\\Python\\Python38\\site-packages', 'C:\\Users\\Andrei\\AppData\\Local\\Programs\\Python\\Python38-32\\lib\\site-packages']
import
Рассмотрим такую конфигурацию
scripts └── my_dir └── path_test.py
Изначально мы внутри директории my_dir
Код path_test.py следующий
print("path test is ok")
python >>> import path_test
path test is ok
Теперь перейдём в директорию scripts
cd .. python >>> import path_test Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'path_test'
Python не смог найти path_test.py
Решение этой проблемы описано в следующем параграфе
sys.path.append
Чтобы избежать этой ошибки можно добавить директорию my_dir в sys.path
>>> import sys >>> sys.path.append('my_dir') >>> import path_test path test is ok!
PYTHONPATH
Ещё один вариант - это задание переменной окружения PYTHONPATH
PYTHONPATH это список путей, который добавляются в sys.path
при запуске Python
Способ зависит от окружения, в котором вы работаете
В Bash это
export PYTHONPATH=my_dir
Если нужно добавить несколько директорий, это делается через :
export PYTHONPATH=path1:path2:path3
Если у вас уже есть переменная PYTHONPATH и нужно добавить в неё директорию не удаляя старую
export PYTHONPATH="path1:$PYTHONPATH"
Подробнее о системных переменных в Linux можно прочитать в статье Linux PATH
В Windows cmd
set PYTHONPATH=my_dir
Добавить несколько директорий сразу
set PYTHONPATH=path1;path2;path3
$env:PYTHONPATH='my_dir'
Подробнее о системных переменных в Windows можно прочитать в статье Windows PATH
Рассмотрим следующую конфигурацию
andrei └── scripts ├── hidden_dir │ └── pythonpath_test.py └── my_dir └── path_test.py
Изначально мы в директории andrei
export PYTHONPATH=/home/andrei/scripts/hidden_dir python >>> import pythonpath_test
PYTHONPATH works
Можно вручную проверить находится ли hidden_dir в sys.path или нет с помощью sys и, например генератора списков
>>> import sys [path for path in sys.path if 'hidden_dir' in path] ['/home/andrei/scripts/hidden_dir']
Если вы уже находитесь в нужной для Python директории, добавить её в PYTHONPATH можно с помощью команды
export PYTHONPATH=$(pwd)
Или
export PYTHONPATH=$(pwd):$PYTHONPATH
Если вы добавляете в PYTHONPATH путь до пакета, нужно добавить путь на один уровень выше, чтобы Python увидел название самого пакета, а не только его содержимое
export PYTHONPATH=$(pwd)