ModuleNotFoundError: No module named 'requests' означает, что импортёр Python не нашёл модуль requests. Это не всегда значит, что библиотека не установлена. Та же ошибка возникает, когда программа запущена другим интерпретатором, локальный пакет оказался вне sys.path, в имени есть опечатка или модуль отсутствует именно в этой версии Python.
Сначала прочитай имя в кавычках в последней строке traceback. Затем проверь интерпретатор и поиск модуля. Устанавливать пакет стоит, только когда знаешь его настоящее имя и видишь, что он нужен проекту. Если в кавычках pandas, переходи сразу к разделу No module named ‘pandas’. Примеры ниже проверены на CPython 3.14.5.
Пакет ищет тот Python, который запущен
Сначала прочитай точное имя модуля
Важна последняя строка, а не только первый импорт в твоём файле:
Traceback (most recent call last):
File "main.py", line 1, in <module>
import report_tool
File "/project/report_tool.py", line 3, in <module>
import openpyxl
ModuleNotFoundError: No module named 'openpyxl'
Программа нашла report_tool, открыла его и остановилась на внутреннем импорте openpyxl. Проверять нужно openpyxl. Если сообщение содержит No module named 'app.settings', Python не нашёл подмодуль settings внутри app; установка пакета с именем app.settings здесь не следует из ошибки.
Не путай эту ошибку с ImportError: cannot import name. Во втором случае модуль найден, но в нём нет запрошенного имени: причина обычно в версии API, циклическом импорте или неверном имени объекта, а не в отсутствующей установке.
No module named ‘pandas’
Самый частый случай этой ошибки. pandas нет в стандартной библиотеке: его ставят отдельно, и ставить нужно в тот Python, которым запускаешь программу. Имя на PyPI и имя в import здесь совпадают, поэтому пакет называется просто pandas:
python -m pip install pandas
В Windows то же самое делают через лаунчер Python: py -3 -m pip install pandas.
Ubuntu и Debian: externally-managed-environment. В Ubuntu 24.04 и Debian 12 системный Python не даёт ставить в себя пакеты через pip:
$ pip install pandas
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.
Это не поломка, а защита по PEP 668: от системного Python зависят программы самой ОС. Создай для проекта виртуальное окружение и поставь pandas туда:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install pandas
python -c "import pandas; print(pandas.__version__)"
3.0.6
После activate команда python запускает Python из .venv — им и запускай программу. Как устроено окружение, разобрано в инструкции по venv. Сообщение pip предлагает и другие пути: пакет дистрибутива sudo apt install python3-pandas — но в Ubuntu 24.04 это pandas 2.1.4, а не 3.0 — и флаг --break-system-packages, который ставит пакет прямо в системный Python. Второй лучше не трогать.
Jupyter Notebook. Тетрадка выполняет код в своём ядре, а pip из терминала может поставить пакет в другой Python. Ставь из самой тетрадки:
%pip install pandas
Магическая команда %pip запускает pip того интерпретатора, на котором работает ядро, и напоминает: Note: you may need to restart the kernel to use updated packages. Если pandas уже импортировали в этой тетрадке, перезапусти ядро.
PyCharm и VS Code. Если pandas установлен, а редактор показывает ту же ошибку, он запускает программу другим интерпретатором. Сверь пути, как в следующем разделе, и выбери в редакторе Python из той .venv, куда ставил пакет.
Без установки. Если нужно просто открыть таблицу и посчитать, в песочнице Python pandas скачивается сам при первом import pandas, как и numpy и matplotlib: ставить ничего не надо, всё работает в браузере. Как читать CSV и выбирать строки — в разборе «pandas DataFrame».
Проверь, какой Python запускает программу
Так бывает, когда пакет установлен в системный Python, а редактор или терминал запускает Python из другой .venv. Узнай путь к интерпретатору той же командой, которой запускаешь проект:
python -c "import sys; print(sys.executable)"
python -m pip --version
Первая команда печатает исполняемый файл Python. Вторая показывает путь к pip и версию Python, к которой он относится. Оба пути должны вести в одно окружение. Например:
/project/.venv/bin/python
pip 25.1.1 from /project/.venv/lib/python3.14/site-packages/pip (python 3.14)
Теперь проверь известное имя устанавливаемого дистрибутива:
python -m pip show Pillow
Location в выводе должен принадлежать той же .venv. Если pip show пишет Package(s) not found, это доказывает только одно: дистрибутив с таким именем не установлен для выбранного Python. Команда ничего не говорит о похожих именах и не подтверждает, что выбран правильный пакет.
Используй python -m pip, а не отдельную команду pip: модуль pip тогда запускает именно тот python, который стоит слева. Создание и активация окружения разобраны в инструкции по venv. Если проект управляет зависимостями через uv, запускай его по сценарию с uv add и uv run, не смешивая два окружения.
Проверь модуль без запуска приложения
importlib.util.find_spec() показывает, сможет ли текущий интерпретатор найти модуль:
python -c "import importlib.util; print(importlib.util.find_spec('PIL'))"
Для найденного модуля команда вернёт ModuleSpec с путём, например:
ModuleSpec(name='PIL', loader=..., origin='/project/.venv/lib/python3.14/site-packages/PIL/__init__.py', ...)
None означает, что обычный механизм импорта не видит PIL в этом окружении. Для верхнеуровневого имени такая проверка не выполняет код самого модуля, поэтому удобна до пробного импорта. После успешного find_spec узнай, какой файл загрузился на самом деле:
python -c "import PIL; print(PIL.__file__)"
Путь может обнаружить другую проблему: например, локальный PIL.py затенил установленную библиотеку. Переименуй такой файл и повтори проверку.
Имя на PyPI может не совпадать с именем в import
В import PIL указано имя импортируемого пакета. В python -m pip install Pillow указано имя дистрибутива. PyPA приводит эту пару как официальный пример несовпадения. Другой дистрибутив может экспортировать несколько импортируемых пакетов, а одно импортируемое имя могут предоставлять разные дистрибутивы.
Поэтому не подставляй текст ошибки в pip install автоматически. Пакет с совпадающим именем на PyPI может оказаться чужим, заброшенным или вредоносным. Найди имя зависимости в pyproject.toml, requirements.txt или документации проекта; для сторонней библиотеки проверь официальный сайт, репозиторий и страницу издателя на PyPI. Если источник зависимости неизвестен, остановись и уточни его, а не перебирай похожие пакеты.
Когда зависимость подтверждена, восстанови окружение из файла проекта:
python -m pip install -r requirements.txt
Для проекта с pyproject.toml, который устанавливается как пакет, команда может быть такой:
python -m pip install -e .
Режим -e полезен в разработке: пакет остаётся связан с исходниками. Не применяй эти команды наугад — выбери ту, которую предусматривает сам проект.
Локальный пакет: рабочая директория и package root
Допустим, проект устроен так:
shop-project/
├── pyproject.toml
└── shop_app/
├── __init__.py
├── cli.py
└── prices.py
В cli.py используется абсолютный импорт:
from shop_app.prices import load_prices
Запускай модуль из корня shop-project, то есть из каталога, который содержит пакет shop_app:
cd shop-project
python -m shop_app.cli
Прямой запуск python shop_app/cli.py меняет начальную точку поиска: первой становится директория shop_app, а её родительский каталог может не попасть туда, где ожидается package root. Запуск через -m сохраняет пакетный контекст и позволяет абсолютному импорту найти shop_app.
Проверь текущую директорию и весь путь поиска одной командой:
python -c "import os, sys; print('cwd:', os.getcwd()); print(*sys.path, sep='\n')"
Python формирует sys.path при старте. Для файла в начале обычно стоит каталог этого файла, а для python -m, python -c и интерактивного запуска — текущая директория. Затем добавляются пути стандартной библиотеки, окружения и site-packages. Если каталог над shop_app отсутствует, исправь команду запуска, установи проект в окружение или перейди в package root.
Почему не стоит дописывать sys.path в коде
Такой фрагмент часто скрывает ошибку запуска:
import sys
sys.path.insert(0, '/home/user/shop-project')
Жёсткий путь работает только на одной машине. Относительный путь зависит от текущей директории, меняет приоритет модулей и может незаметно подхватить одноимённый файл не из того места. В тестах, редакторе и продакшене список путей снова различится.
Постоянный фикс — корректная структура пакета и одна воспроизводимая команда запуска: python -m shop_app.cli, python -m pip install -e . либо установка зависимостей проекта в его .venv. Ручное изменение sys.path оправдано в редких загрузчиках и одноразовой диагностике, но не как обычная настройка приложения.
Проверь опечатку, регистр и версию Python
Импортируемые имена чувствительны к регистру. import Requests и import requests — разные имена; на файловой системе без учёта регистра ошибка может временно не проявиться и сломать запуск на Linux. Сверь каждую часть имени с документацией и именем файла: user_profile.py импортируется как user_profile, а не user-profile.
Модуль стандартной библиотеки тоже зависит от версии Python. Например, tomllib появился в Python 3.11, а несколько устаревших модулей, включая imghdr, удалены в Python 3.13. Проверь фактическую версию и официальный индекс модулей для неё:
python --version
python -c "import importlib.util; print(importlib.util.find_spec('tomllib'))"
Если код рассчитан на другую версию, выбери поддерживаемый интерпретатор или предусмотренную проектом замену. Не пытайся «вернуть» стандартный модуль установкой случайного одноимённого дистрибутива из PyPI.
Симптом, проверка и исправление
| Симптом | Что проверить | Что исправить |
|---|---|---|
pip install pandas отвечает externally-managed-environment | Это системный Python Ubuntu или Debian | Создать .venv и ставить pandas туда |
| В терминале pandas импортируется, а в Jupyter — нет | Python ядра тетрадки | Выполнить %pip install pandas в самой тетрадке |
No module named 'requests', хотя установка уже была | sys.executable, python -m pip --version | Выбрать одну .venv и запускать pip через тот же Python |
python -m pip show Pillow находит пакет, а import PIL падает | find_spec('PIL'), поле Location | Убрать смешение окружений или восстановить установку по файлу зависимостей |
Имя после No module named не совпадает с первым импортом | Последние строки traceback | Исправить или установить именно вложенную зависимость, подтверждённую проектом |
Имя из import не находится на PyPI или выглядит подозрительно | pyproject.toml, документацию и официальный репозиторий | Найти настоящее имя дистрибутива; не ставить пакет по догадке |
| Локальный пакет находится в репозитории, но не импортируется | cwd, sys.path, каталог над пакетом | Запустить из package root через python -m или установить проект с -e . |
| Ошибка появляется только на Linux или в CI | Регистр букв в импорте и имени файла | Привести написание к точному имени модуля |
| Стандартный модуль есть в документации, но не в окружении | python --version, индекс модулей этой версии | Использовать совместимую версию Python или документированную замену |
find_spec показывает неожиданный файл проекта | Имя локального .py-файла | Переименовать файл, который затеняет нужный пакет |
Короткий порядок диагностики
- Прочитай точное имя после
No module namedи последний импорт в traceback. - Сравни
sys.executableс путём изpython -m pip --version. - Для подтверждённого дистрибутива выполни
python -m pip show <имя>. - Проверь импортируемое имя через
importlib.util.find_spec(). - Для локального пакета проверь
cwd,sys.path, package root и запуск черезpython -m. - Только после этого устанавливай объявленную зависимость или исправляй структуру проекта.
Если программа после исправления импорта падает уже внутри try, обработку таких сбоев стоит строить через конкретные исключения. Базовые схемы собраны в статье «try/except в Python».
Не нашёл свою ошибку в разборе? Вставь трейсбек в расшифровщик ошибок Python: он переведёт сообщение, назовёт причину и покажет починку.