Модули и пакеты Python: import, pip, venv и библиотеки простыми словами
Модуль в Python — это файл .py, пакет — папка модулей, библиотека — набор пакетов, который подключают командой import. Сторонние библиотеки ставят через pip (или uv) в виртуальное окружение venv — изолированную папку с интерпретатором и пакетами одного проекта, чтобы версии разных проектов не конфликтовали.
Модуль в Python — это обычный файл с кодом, а import — способ взять из него функции и классы. Из модулей собирают пакеты, из пакетов — библиотеки, а чтобы сторонние библиотеки разных проектов не мешали друг другу, их ставят в виртуальное окружение venv. Разберём всю цепочку: что происходит при импорте, как устроен пакет, как работают pip и venv в Python и что за ленивые импорты появились в Python 3.15.
Модуль, пакет, библиотека: в чём разница
| Понятие | Что это | Пример |
|---|---|---|
| Модуль | Один файл .py; имя модуля = имя файла без расширения | categories.py → import categories |
| Пакет | Папка с модулями и файлом __init__.py | expenses/report.py → from expenses.report import build |
| Библиотека | Готовый набор модулей и пакетов для какой-то задачи | requests, pandas, стандартная pathlib |
| Дистрибутив (пакет PyPI) | Архив, который ставит pip | pip install requests |
Слова «библиотека», «пакет» и «модуль» в разговоре часто смешивают — это нормально. Важно понимать, что технически import всегда загружает модуль или пакет, а pip устанавливает дистрибутив с PyPI, внутри которого лежат пакеты.
Как работает import в Python
Есть несколько форм импорта, и все они встречаются в реальном коде:
import math # весь модуль, обращение math.sqrt
from math import sqrt, pi # отдельные имена
import datetime as dt # псевдоним
from collections import Counter as C
print(math.sqrt(16), sqrt(9), pi)
print(dt.date.today())
Псевдонимы общеприняты для крупных библиотек: import numpy as np, import pandas as pd. Конструкцию from module import * лучше не использовать: она засоряет пространство имён и прячет, откуда взялось имя.
Что делает import на самом деле
- Ищет модуль в кэше
sys.modules. Если он уже загружен — просто возвращает его. - Если нет — ищет файл по списку папок
sys.path: папка запущенного скрипта, стандартная библиотека, site-packages окружения. - Выполняет найденный файл целиком сверху вниз.
- Кладёт объект модуля в кэш и связывает его с именем.
Из этого следуют два практических вывода. Повторный import того же модуля почти бесплатен — код второй раз не выполняется. А весь код верхнего уровня в модуле, включая print и тяжёлые вычисления, срабатывает при импорте.
import sys
for p in sys.path:
print(p)
print("math" in sys.modules)
if __name__ == "__main__"
Раз импорт выполняет файл, нужен способ отличить «меня запустили как скрипт» от «меня импортировали». Для этого есть переменная __name__: при запуске файла она равна "__main__", при импорте — имени модуля.
# categories.py
def guess(title: str) -> str:
return "еда" if "кафе" in title.lower() else "прочее"
if __name__ == "__main__":
print(guess("Кафе у дома")) # выполнится только при python categories.py
Для пакета есть альтернатива: файл __main__.py внутри и запуск python -m expenses.
Стандартные модули Python
Python поставляется «с батарейками»: сотни встроенных модулей доступны сразу, без установки. Самые ходовые:
| Модуль | Для чего |
|---|---|
os, sys, pathlib, shutil | Система, пути, файлы |
json, csv, pickle | Форматы данных |
datetime, time, calendar | Дата и время |
math, random, statistics, fractions | Числа |
re, string | Работа с текстом |
collections, itertools, functools | Структуры данных и итераторы |
logging, argparse, subprocess | Логи, аргументы командной строки, запуск программ |
asyncio, threading | Асинхронность и потоки |
Полный список модулей стандартной библиотеки хранится в sys.stdlib_module_names (Python 3.10+). Посмотреть, что есть у модуля, можно через dir(math) и help(math).
Свой пакет: структура проекта
Когда модулей становится много, их собирают в пакет. Распространённая раскладка — src-layout:
expenses-project/
├── pyproject.toml
└── src/
└── expenses/
├── __init__.py
├── cli.py
├── parsing.py
├── categories.py
└── report.py
Внутри пакета модули импортируют друг друга через имя пакета (from expenses.categories import guess) или относительно (from .categories import guess). Относительный импорт работает только внутри пакета, а не в файле, запущенном напрямую как скрипт.
pip в Python: установка библиотек
Сторонние библиотеки лежат в каталоге PyPI, а ставит их утилита pip, которая идёт вместе с Python. Надёжнее всего вызывать её через интерпретатор — так библиотека точно попадёт в тот Python, которым вы запускаете код.
python -m pip install requests # установить
python -m pip install "pandas>=2.3" # с ограничением версии
python -m pip install --upgrade requests
python -m pip uninstall requests # удалить
python -m pip list # список установленных пакетов
python -m pip show requests # версия и зависимости
python -m pip freeze > requirements.txt
python -m pip install -r requirements.txt
На Windows вместо python часто используют лаунчер py. Если pip не найден, его ставит встроенный модуль: python -m ensurepip --upgrade.
Популярные библиотеки Python
Сторонних пакетов на PyPI сотни тысяч, но в большинстве проектов встречается один и тот же короткий список. Начинать стоит с него, а не с поиска экзотики.
| Задача | Библиотеки |
|---|---|
| HTTP-запросы и API | requests, httpx |
| Анализ данных и таблицы | pandas, numpy |
| Графики | matplotlib |
| Веб-сервисы | fastapi, django, flask |
| Тесты | pytest |
| Изображения | pillow (импортируется как PIL) |
Обратите внимание: имя для установки и имя для импорта не всегда совпадают. Ставят pip install pillow, а пишут from PIL import Image; ставят opencv-python, а импортируют cv2. Если import падает сразу после установки, проверьте, под каким именем пакет импортируется, в его документации.
Установка библиотек в Linux
В свежих Debian и Ubuntu команда pip install в системный Python заканчивается ошибкой externally-managed-environment (PEP 668). Это защита: системный Python принадлежит менеджеру пакетов ОС, и pip не должен его ломать. Правильное решение — не --break-system-packages, а виртуальное окружение.
venv в Python: виртуальное окружение
Виртуальное окружение — отдельная папка со своей копией интерпретатора (ссылкой на него) и своим site-packages. Библиотеки, установленные в нём, видны только этому проекту. Так одному проекту можно иметь Django 4, а соседнему — Django 5, и они не конфликтуют.
Модуль venv встроен в Python, отдельно его устанавливать не нужно (в Debian/Ubuntu иногда требуется системный пакет python3-venv).
# создать окружение в папке .venv
python -m venv .venv
# активировать: Linux и macOS
source .venv/bin/activate
# активировать: Windows PowerShell
.venv\Scripts\Activate.ps1
# теперь pip ставит пакеты внутрь .venv
python -m pip install requests
python -c "import sys; print(sys.prefix)"
# выйти из окружения
deactivate
После активации в начале строки терминала появляется (.venv). Папку окружения не коммитят в git (добавьте .venv/ в .gitignore) и не переносят между машинами — вместо этого фиксируют список зависимостей и пересоздают окружение. Если PowerShell запрещает запуск скрипта активации, разрешите его для пользователя: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.
uv и pyproject.toml
Современные проекты описывают зависимости в pyproject.toml. Менеджер uv, который используется в курсе, объединяет создание окружения и установку: uv add pandas скачивает пакет, записывает его в pyproject.toml и фиксирует точные версии в uv.lock. Коллега клонирует проект, выполняет uv sync — и получает окружение один в один.
[project]
name = "expenses"
version = "0.1.0"
requires-python = ">=3.15"
dependencies = [
"pandas>=2.3",
]
[project.scripts]
expenses = "expenses.cli:main"
Ленивые импорты в Python 3.15 (PEP 810)
Главная новинка 3.15 в этой теме — ключевое слово lazy. Тяжёлые библиотеки грузятся долго: в замере курса на образе python:3.15-slim обычный import pandas занял около 415 мс, а lazy import pandas — около 13 мс. Для CLI-утилиты, которую запускают ради --help, разница огромная.
lazy import pandas as pd
lazy from expenses.report import build_report
def main() -> None:
...
df = pd.read_csv(path) # настоящая загрузка pandas — здесь
Вместо модуля в имя кладётся прокси-объект (types.LazyImportType), а настоящий импорт происходит при первом обращении к имени. Если до него дело не дошло, время не тратится вовсе.
Ограничения lazy import
- Разрешён только на верхнем уровне модуля: внутри функции, класса или
try/except—SyntaxError. lazy from x import *запрещён.ModuleNotFoundErrorвсплывёт не при старте, а при первом использовании.- Побочные эффекты модуля (регистрация плагинов и т.п.) сдвигаются во времени.
Сделать ленивыми все импорты сразу можно флагом -X lazy_imports=all или переменной PYTHON_LAZY_IMPORTS=all, исключения задаются через sys.set_lazy_imports_filter(). Для кода, который должен работать и на старых версиях, есть переменная модуля __lazy_modules__ = ["pandas"]: 3.15 сделает перечисленные импорты ленивыми, а старые версии просто выполнят обычный import. Где тратится время при старте, покажет python -X importtime -c "import pandas". Выигрывают прежде всего программы с частыми короткими запусками; долгоживущему серверу ленивость почти ничего не даёт.
Типичные ошибки
ModuleNotFoundError: No module named 'requests'— библиотека поставлена в другой Python или окружение не активировано. Проверьтеpython -m pip show requestsтем же интерпретатором.- Свой файл назван
json.py,random.pyилиcsv.py— папка скрипта стоит вsys.pathпервой, и он перекрывает стандартный модуль. Python 3.13+ подсказывает в ошибке «consider renaming». Переименуйте файл и удалите__pycache__. - Циклический импорт:
a.pyимпортируетb.py, а тот —a.py. Вынесите общее в третий модуль или импортируйте внутри функции. pipзапущен внутри интерпретатора Python (>>> pip install) — получитеSyntaxError. Команды pip выполняются в терминале.
Итог
Модуль — файл, пакет — папка модулей, библиотека — их готовый набор; import ищет модуль в кэше и по sys.path и выполняет его один раз. Сторонние библиотеки ставьте через pip или uv только в виртуальное окружение venv — так проекты не мешают друг другу, а окружение легко воспроизвести. В курсе по Python эта тема разобрана на практике: трекер расходов превращается в пакет с зависимостями и быстрым стартом за счёт ленивых импортов.
Частые вопросы
Нужно ли создавать venv для каждого проекта?
Да, это хорошая практика: у каждого проекта свои версии библиотек, и отдельное окружение исключает конфликты и не засоряет системный Python.
Чем pip отличается от uv?
pip только устанавливает пакеты, а uv ещё создаёт окружение, записывает зависимости в pyproject.toml и фиксирует точные версии в lock-файле; при этом он заметно быстрее.
Как посмотреть список установленных библиотек Python?
Выполните python -m pip list в нужном окружении; pip freeze выведет тот же список в формате для requirements.txt.
Где хранятся установленные модули?
В папке site-packages текущего окружения; путь к конкретному модулю показывает атрибут __file__, например import requests; print(requests.__file__).
Можно ли перенести папку venv на другой компьютер?
Нет, окружение привязано к путям и интерпретатору машины; переносят список зависимостей и создают окружение заново.
Эта тема подробно разобрана с практикой в курсе «Python 3.15: от новичка до профи».
Перейти к курсу