Содержание
- Что вообще означает эта ошибка
- Диагностика за 30 секунд: три команды
- Причина 1. На машине несколько Python, и pip достался не тому
- Причина 2. Виртуальное окружение не активировано или активировано чужое
- Причина 3. Файл рядом со скриптом затеняет пакет
- Причина 4. Имя для импорта не совпадает с именем пакета
- Причина 5. Редактор, Jupyter и сборщик запускают свой интерпретатор
- Что изменилось к 2026 году и ломает старые инструкции
- Частые вопросы
- Порядок действий, если ничего не помогло
Разбираемся с ошибкой ModuleNotFoundError: no module named
Черновик готовит редакция с помощью ИИ. За стандарт издания отвечает главный редактор — Валерий Курземнек.
Короткий ответ. В подавляющем большинстве случаев ModuleNotFoundError: No module named 'requests' означает одно: пакет установлен не в тот Python, которым вы запускаете скрипт. Чините одной строкой — ставьте пакет тем же самым интерпретатором, которым запускаете код:
# Linux / macOS
python3 -m pip install requests
# Windows
py -m pip install requests
Затем запускайте скрипт тем же интерпретатором: python3 app.py или py app.py. Если работаете в виртуальном окружении — сначала активируйте его, потом ставьте пакет.
Именно такую команду даёт официальная документация библиотеки: «To install Requests, simply run this simple command in your terminal of choice: $ python -m pip install requests» (requests.readthedocs.io). Обратите внимание на форму python -m pip, а не голое pip — разница между ними и есть причина ошибки в половине случаев. Документация pip объясняет прямо: «python -m pip executes pip using the Python interpreter you specified as python. So /usr/bin/python3.7 -m pip means you are executing pip for your interpreter located at /usr/bin/python3.7».
Голое pip — отдельный исполняемый файл, который система находит по PATH, и принадлежать он может другому Python, не тому, что запустит ваш скрипт. Тогда установка проходит успешно, а импорт падает — классическое «поставил, а он не видит».
Что вообще означает эта ошибка
ModuleNotFoundError — подкласс ImportError. Он возникает в одной-единственной точке: интерпретатор прошёл по всем каталогам из sys.path и не нашёл там ни пакета, ни модуля с таким именем. Ошибка не говорит «пакета нет на компьютере». Она говорит «его нет там, куда смотрит этот процесс Python».
Пакет может лежать на диске в трёх копиях, а падать всё равно будет — если запускающий интерпретатор ни одну не видит. Чинить нужно не установку, а совпадение двух адресов: куда положил pip и откуда читает python.
Диагностика за 30 секунд: три команды

Не гадайте по списку причин — снимите показания. Три команды отвечают на вопрос «кто и куда» и сразу отсекают три четверти вариантов.
Команда 1. Чем вы запускаете код.
python -c "import sys; print(sys.executable)"
Реальный вывод на Windows с системным Python:
C:\Python314\python.exe
Команда 2. Какому Python принадлежит ваш pip.
python -m pip --version
Реальный вывод:
pip 25.3 from C:\Python314\Lib\site-packages\pip (python 3.14)
Как читать. Путь из второй команды должен начинаться с той же папки, что путь из первой. C:\Python314\python.exe и C:\Python314\Lib\site-packages\pip — совпадают, установка попадёт по адресу. Если во второй строке другая папка — например, C:\Users\user\AppData\Local\Programs\Python\Python311\Lib\site-packages\pip, — вы ставите пакеты в Python 3.11, а запускаете 3.14. Это и есть диагноз.
Команда 3. Стоит ли пакет там, где вы его ищете.
python -m pip show requests
Если стоит, вывод содержит строку Location — это и есть каталог, откуда пакет будет импортирован:
Name: requests
Version: 2.33.1
Summary: Python HTTP for Humans.
Location: C:\Users\user\AppData\Roaming\Python\Python314\site-packages
Requires: certifi, charset_normalizer, idna, urllib3
Если не стоит, pip отвечает ровно одной строкой — не ошибкой, а предупреждением, и это часто проглядывают:
WARNING: Package(s) not found: requests
Дальше решение развилки:
pip showничего не нашёл → пакета в этом окружении нет, ставьте:python -m pip install requests.pip showнашёл, а импорт всё равно падает → интерпретаторы разные либо путь затенён локальным файлом. Разбор — в разделах ниже.
Важная деталь: команды 1 и 2 нужно запускать в той же самой консоли и из той же самой папки, откуда падает скрипт. Смена терминала меняет активное окружение и обнуляет замер.
Причина 1. На машине несколько Python, и pip достался не тому
Это причина номер один и на Windows, и на macOS. Проверьте, сколько интерпретаторов у вас реально установлено.
Windows. Лаунчер py умеет перечислять все установленные версии с путями:
py -0p
Реальный вывод на рабочей машине:
-V:3.14 * C:\Python314\python.exe
-V:3.11 C:\Users\user\...\Python311\python.exe
-V:3.10 C:\Users\user\...\Python310\python.exe
Звёздочка помечает версию по умолчанию. Дополнительно посмотрите, какие python.exe вообще видны через PATH:
where python
C:\Python314\python.exe
C:\Users\user\AppData\Local\Microsoft\WindowsApps\python.exe
C:\Users\user\AppData\Local\Programs\Python\Python311\python.exe
Сколько строк в выводе — столько кандидатов на роль «того самого» интерпретатора, и побеждает первый. Отдельно отметьте строку с WindowsApps: это не полноценный Python, а заглушка Microsoft Store. Если она стоит в PATH выше настоящей установки, команда python открывает магазин приложений вместо запуска кода, а pip при этом указывает на нормальную установку. Расхождение гарантировано.
Linux / macOS. Та же проверка — which -a python3.
Как чинить. Не правьте PATH — это долго и ломается на следующей установке. Просто перестаньте вызывать pip отдельной командой. Правило простое: чем запускаете скрипт, тем и ставьте пакет.
# Windows: явно указать версию
py -3.11 -m pip install requests
py -3.11 app.py
# Linux / macOS
python3.11 -m pip install requests
python3.11 app.py
Официальное руководство по установке пакетов формулирует это как норму: проверять доступность pip нужно командой python3 -m pip --version, а на Windows — py -m pip --version (документация pip). Форма -m не оставляет системе выбора: pip запускается внутри конкретного интерпретатора и ставит пакет в его собственный site-packages.
Причина 2. Виртуальное окружение не активировано или активировано чужое
Виртуальное окружение — это отдельный набор пакетов со своим site-packages. Пакет, установленный глобально, внутри venv не виден, и наоборот. Отсюда самый обидный сценарий: requests стоит в системе годами, а свежесозданный venv про него не знает.
Воспроизводится за две команды. Создаём чистое окружение и запускаем им скрипт, который импортирует requests:
python -m venv .venv
.venv\Scripts\python.exe app.py
Настоящий трейсбек:
Traceback (most recent call last):
File "C:\projects\myapp\app.py", line 1, in <module>
import requests
ModuleNotFoundError: No module named 'requests'
Как активировать. Команда зависит от оболочки — таблица из документации venv:
| Платформа | Оболочка | Команда активации |
|---|---|---|
| POSIX | bash/zsh | source .venv/bin/activate |
| POSIX | fish | source .venv/bin/activate.fish |
| Windows | cmd.exe | .venv\Scripts\activate.bat |
| Windows | PowerShell | .venv\Scripts\Activate.ps1 |
Активация не делает магии: она просто дописывает каталог окружения в начало PATH, чтобы команда python вызывала интерпретатор окружения. Документация подчёркивает, что активация вообще не обязательна: «You don’t specifically need to activate a virtual environment, as you can just specify the full path to that environment’s Python interpreter when invoking Python».
Практический вывод: если активация в вашей консоли не срабатывает (частая беда в PowerShell с политикой выполнения скриптов), не воюйте с ней — вызывайте интерпретатор окружения по полному пути. Работает всегда:
.venv\Scripts\python.exe -m pip install requests
.venv\Scripts\python.exe app.py
Как проверить, что вы внутри окружения. Надёжный признак — не приглашение в консоли и не переменная VIRTUAL_ENV. Документация прямо предупреждает: раз активация не обязательна, «VIRTUAL_ENV cannot be relied upon to determine whether a virtual environment is being used». Достоверная проверка — сравнение префиксов:
python -c "import sys; print(sys.prefix != sys.base_prefix)"
True — вы в venv. False — работаете глобальным Python, что бы ни было написано в приглашении терминала. Разбор работы с изолированными средами — в отдельном материале: как активировать venv в Python.
Причина 3. Файл рядом со скриптом затеняет пакет

Классический совет «переименуйте свой requests.py» верен по сути, но неверен в деталях — и из-за этого люди отбрасывают правильную гипотезу.
Порядок поиска описан в документации Python: «When a module named spam is imported, the interpreter first searches for a built-in module with that name… If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path». Первым элементом этого списка идёт каталог запускаемого скрипта: «The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended» (docs.python.org).
Что происходит на самом деле. Положите рядом с app.py файл requests.py — и получите вовсе не ModuleNotFoundError:
Traceback (most recent call last):
File "C:\projects\myapp\app.py", line 2, in <module>
print(requests.get("https://example.com").status_code)
^^^^^^^^^^^^
AttributeError: module 'requests' has no attribute 'get'
Импорт прошёл — просто импортировался ваш файл. Поэтому: если вы видите AttributeError: module 'X' has no attribute ... сразу после установки пакета, ищите в папке файл с именем X.py.
А вот когда затенение действительно даёт ModuleNotFoundError. Когда вы назвали свой файл именем не самого пакета, а его зависимости. Пустой файл urllib3.py рядом со скриптом ломает установленный requests:
Traceback (most recent call last):
File "C:\projects\myapp\app.py", line 1, in <module>
import requests
File "...\site-packages\requests\__init__.py", line 45, in <module>
from .exceptions import RequestsDependencyWarning
File "...\site-packages\requests\exceptions.py", line 8, in <module>
from urllib3.exceptions import HTTPError as BaseHTTPError
ModuleNotFoundError: No module named 'urllib3.exceptions'; 'urllib3' is not a package
Признак этого класса в трейсбеке безошибочный: ошибка возникает внутри файлов пакета, а не в вашей строке import, и в сообщении есть хвост is not a package. Лечение — переименовать свой файл и удалить каталог __pycache__ рядом с ним.
Деталь, которую стоит знать: пустая папка с именем requests рядом со скриптом установленный пакет не перебивает — импорт отрабатывает нормально. Затеняет именно файл .py или каталог с __init__.py.
Посмотреть список каталогов поиска целиком — python -c "import sys; print(*sys.path, sep='\n')". Первая строка и есть каталог, из которого «прилетает» лишний файл. Саму подстановку каталога скрипта можно отключить флагом -P или переменной PYTHONSAFEPATH: «Don’t prepend a potentially unsafe path to sys.path».
Причина 4. Имя для импорта не совпадает с именем пакета

Отдельный класс ошибок, который командой pip install лечится только если знать правильное имя. У requests имена совпадают: ставим requests, импортируем requests. У доброй половины популярных библиотек — нет. Человек пишет pip install PIL, получает «пакет не найден», ставит наугад и продолжает ловить ModuleNotFoundError.
Таблица проверена запуском: в чистый venv поставлены пакеты из левой колонки, импорт выполнен по именам из правой.
| Команда установки | Как импортировать | Проверено, версия |
|---|---|---|
pip install Pillow |
from PIL import Image |
pillow 12.3.0 |
pip install PyYAML |
import yaml |
PyYAML 6.0.3 |
pip install beautifulsoup4 |
import bs4 |
beautifulsoup4 4.15.0 |
pip install python-dotenv |
import dotenv |
python-dotenv 1.2.2 |
pip install pyTelegramBotAPI |
import telebot |
pyTelegramBotAPI 4.36.0 |
pip install requests |
import requests |
requests 2.34.2 |
Тот же разрыв встречается в opencv-python → import cv2 и scikit-learn → import sklearn. Универсальный способ проверить, не догадываясь: посмотреть, что именно установлено в текущем окружении.
python -m pip list
Фрагмент реального вывода:
Package Version
------------------ ---------
beautifulsoup4 4.15.0
pillow 12.3.0
pyTelegramBotAPI 4.36.0
requests 2.34.2
А чтобы узнать, какие имена для импорта даёт конкретный пакет, посмотрите файлы, которые он положил на диск:
python -m pip show -f Pillow
В списке файлов будет каталог PIL — это и есть имя для import.
Опечатки. Сюда же относится банальный промах в написании. Python не подсказывает похожие имена модулей, ответ будет сухим:
Traceback (most recent call last):
File "C:\projects\myapp\bad.py", line 1, in <module>
import reqests
ModuleNotFoundError: No module named 'reqests'
Правило чтения: имя в кавычках после «No module named» — это ровно то, что вы написали в коде. Сравните его посимвольно со строкой из pip list, прежде чем искать более сложные причины. Регистр тоже важен: import Requests даёт ModuleNotFoundError: No module named 'Requests' даже на Windows, где файловая система регистр не различает.

- ПОКАЖЕМ, КАК РАЗВЕРНУТЬ МОДЕЛЬ нейросети DEEPSEEK R1 ПРЯМО НА СВОЁМ КОМПЬЮТЕРЕ
- Где и как применять? Потестируем модель после установки на разных задачах
- Как дообучить модель под себя?
Причина 5. Редактор, Jupyter и сборщик запускают свой интерпретатор
Терминал и IDE — разные среды. В консоли всё импортируется, по кнопке «Run» падает: редактор запускает скрипт своим интерпретатором, а не тем, которым вы ставили пакет.
Не спорьте с настройками вслепую — заставьте программу саму сказать, чем она работает. Вставьте в начало падающего скрипта две строки и запустите его так же, как запускали до этого:
import sys
print(sys.executable)
print(sys.prefix != sys.base_prefix)
Первая строка покажет реальный интерпретатор, вторая — True, если это виртуальное окружение. Сравните вывод с тем, что дала python -m pip --version в терминале. Разошлось — причина найдена: переключите интерпретатор проекта в настройках IDE на тот, где стоит пакет, либо поставьте пакет в тот, который выбрала IDE.
Jupyter и блокноты. Ядро блокнота — тоже отдельный интерпретатор, и !pip install requests в ячейке может уйти мимо него. Надёжная форма установки прямо из блокнота использует интерпретатор текущего ядра:
import sys
!{sys.executable} -m pip install requests
Собранный .exe. Если ошибка появляется не в разработке, а только у готового файла после сборки, причина другая: анализатор зависимостей не увидел импорт, потому что тот сделан динамически. Тема разобрана отдельно — превращаем Python-скрипт в исполняемый файл.
Когда нужен PYTHONPATH
Переменная PYTHONPATH нужна не для установленных из pip пакетов, а для вашего собственного кода, который лежит вне текущей папки. Документация описывает её так: «Augment the default search path for module files. The format is the same as the shell’s PATH: one or more directory pathnames separated by os.pathsep (e.g. colons on Unix or semicolons on Windows). Non-existent directories are silently ignored».
Обратите внимание на последнюю фразу: несуществующие каталоги игнорируются молча. Опечатка в пути не даст ни ошибки, ни предупреждения — вы увидите только ModuleNotFoundError и решите, что переменная не работает.
# Linux / macOS
export PYTHONPATH=/home/user/myproject
# Windows, PowerShell
$env:PYTHONPATH = "C:\projects\myapp"
Для установленных из pip пакетов правка PYTHONPATH — плохое решение: чинит один запуск и ломает воспроизводимость на другой машине.
Что изменилось к 2026 году и ломает старые инструкции
Часть советов из статей трёх-четырёхлетней давности сегодня сама порождает ModuleNotFoundError. Три изменения, о которые спотыкаются чаще всего.
1. distutils удалён. В Python 3.12 пакет вырезали из стандартной библиотеки по PEP 632: «Remove the distutils package. See the migration guide for advice replacing the APIs it provided. The third-party Setuptools package continues to provide distutils, if you still require it in Python 3.12 and beyond». Поэтому ModuleNotFoundError: No module named 'distutils' на свежем Python — не поломка установки, а ожидаемое поведение. Лечение:
python -m pip install setuptools
2. В новом venv больше нет setuptools. Тот же релиз изменил поведение venv: «Do not pre-install setuptools in virtual environments created with venv. This means that distutils, setuptools, pkg_resources, and easy_install will no longer available by default; to access these run pip install setuptools in the activated virtual environment». Отсюда внезапные No module named 'pkg_resources' в окружении, где «ничего не меняли»: раньше пакет приезжал сам, теперь его нужно ставить явно.
3. Системный Python защищён от установки пакетов. На Ubuntu, Debian и в Homebrew установка в системный интерпретатор блокируется: если в каталоге стандартной библиотеки лежит файл-маркер EXTERNALLY-MANAGED, установщик обязан отказать — «package installation into this Python interpreter’s directory are disabled outside of a virtual environment». Рекомендация из спецификации дословно: «To install Python packages system-wide, try apt install python3-xyz, where xyz is the package you are trying to install. If you wish to install a non-Debian-packaged Python package, create a virtual environment using python3 -m venv path/to/venv».
Рецепт для Linux — не ломать защиту флагами, а работать в окружении:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install requests
Отдельный случай: No module named ‘pip’
Если из строя вышел сам pip, ставить им что-либо бессмысленно. Восстанавливается штатным модулем, входящим в поставку Python:
# Linux / macOS
python3 -m ensurepip --default-pip
# Windows
py -m ensurepip --default-pip
Затем проверьте результат командой python -m pip --version — она же покажет, к какому именно интерпретатору восстановленный pip привязан.
Фиксация зависимостей, чтобы ошибка не вернулась
Разовая установка чинит одну машину. Чтобы проект собирался у всех одинаково, зафиксируйте состав окружения:
python -m pip freeze > requirements.txt
python -m pip install -r requirements.txt
Обе команды тоже должны выполняться нужным интерпретатором — через -m это получается само.
Частые вопросы
Почему pip говорит, что requests установлен, а импорт всё равно падает?
Потому что pip и запускающий скрипт Python — разные интерпретаторы. Сравните вывод python -m pip --version и python -c "import sys; print(sys.executable)": путь к pip должен лежать внутри той же папки, что и путь к интерпретатору. Если папки разные, ставьте пакет командой python -m pip install requests.
Чем отличается pip install от python -m pip install?
Голое pip — это отдельная программа, которую система ищет по переменной PATH, и она может принадлежать другому Python. Форма python -m pip запускает pip внутри конкретного интерпретатора, поэтому пакет гарантированно попадает в то окружение, из которого вы потом импортируете.
Почему ошибка появилась сразу после создания виртуального окружения?
Новое окружение содержит только сам Python и pip, глобально установленные пакеты в него не переносятся. Активируйте окружение и поставьте зависимости заново: python -m pip install -r requirements.txt.
Может ли собственный файл в папке проекта вызвать ModuleNotFoundError?
Да, но только если он назван именем зависимости пакета. Файл requests.py рядом со скриптом даёт AttributeError: module 'requests' has no attribute 'get', а файл urllib3.py — ModuleNotFoundError: No module named 'urllib3.exceptions'. Признак в трейсбеке: ошибка возникает внутри файлов пакета, а не в вашей строке import.
Что делать, если ошибка возникает только в PyCharm или VS Code?
Редактор запускает код своим интерпретатором. Добавьте в начало скрипта import sys; print(sys.executable), запустите через кнопку Run и сравните путь с терминальным. Дальше либо переключите интерпретатор проекта в настройках IDE, либо поставьте пакет в тот, который выбрала IDE.
Порядок действий, если ничего не помогло
- Создайте чистое окружение:
python -m venv .venv— это отсекает мусор прежних установок. - Поставьте зависимости его интерпретатором по полному пути, без активации.
- Запустите скрипт тем же полным путём. Заработало — дело было в окружении, а не в коде.
- Не заработало — переименуйте файл скрипта, удалите
__pycache__и повторите: остаётся затенение именем.
Ошибка ModuleNotFoundError: No module named почти никогда не про сам пакет. Она про несовпадение двух адресов: куда положил pip и откуда читает python. Сведите адреса — и ошибка исчезнет.
Смежное: как моделировать взаимодействие веб-страниц с Python — там requests работает на практике, и обзор нейросетей для генерации, анализа и проверки кода.
