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

URL: https://skillaria.top/ru/guides/python/moduli-python

Модуль в 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 на самом деле

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-запросы и 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 эта тема разобрана на практике: трекер расходов превращается в пакет с зависимостями и быстрым стартом за счёт ленивых импортов.

## FAQ

**Нужно ли создавать 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 на другой компьютер?**

Нет, окружение привязано к путям и интерпретатору машины; переносят список зависимостей и создают окружение заново.


---
Source: Skillaria.Top (https://skillaria.top)
