Основы

Модули и пакеты Python: import, pip, venv и библиотеки простыми словами

Обновлено: · Skillaria.Top

Модуль в Python — это файл .py, пакет — папка модулей, библиотека — набор пакетов, который подключают командой import. Сторонние библиотеки ставят через pip (или uv) в виртуальное окружение venv — изолированную папку с интерпретатором и пакетами одного проекта, чтобы версии разных проектов не конфликтовали.

Модуль в Python — это обычный файл с кодом, а import — способ взять из него функции и классы. Из модулей собирают пакеты, из пакетов — библиотеки, а чтобы сторонние библиотеки разных проектов не мешали друг другу, их ставят в виртуальное окружение venv. Разберём всю цепочку: что происходит при импорте, как устроен пакет, как работают pip и venv в Python и что за ленивые импорты появились в Python 3.15.

Модуль, пакет, библиотека: в чём разница

ПонятиеЧто этоПример
МодульОдин файл .py; имя модуля = имя файла без расширенияcategories.py → import categories
ПакетПапка с модулями и файлом __init__.pyexpenses/report.py → from expenses.report import build
БиблиотекаГотовый набор модулей и пакетов для какой-то задачиrequests, pandas, стандартная pathlib
Дистрибутив (пакет PyPI)Архив, который ставит pippip 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 на самом деле

  1. Ищет модуль в кэше sys.modules. Если он уже загружен — просто возвращает его.
  2. Если нет — ищет файл по списку папок sys.path: папка запущенного скрипта, стандартная библиотека, site-packages окружения.
  3. Выполняет найденный файл целиком сверху вниз.
  4. Кладёт объект модуля в кэш и связывает его с именем.

Из этого следуют два практических вывода. Повторный 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-запросы и APIrequests, 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: от новичка до профи».

Перейти к курсу