EasyТеория4 min

Пакеты и виртуальные окружения

Структура пакетов с __init__.py, виртуальные окружения venv, менеджер пакетов pip и современные инструменты

Пакеты позволяют организовать модули в иерархическую структуру. Виртуальные окружения изолируют зависимости проектов друг от друга. Вместе они составляют основу управления Python-проектами.

Что такое пакет

Пакет -- это директория, содержащая модули Python и специальный файл __init__.py. Начиная с Python 3.3, существуют также namespace-пакеты без __init__.py, но классические пакеты с ним остаются стандартом.

myproject/
    mypackage/
        __init__.py
        models.py
        services.py
        utils/
            __init__.py
            validators.py
            formatters.py

Файл __init__.py

Этот файл выполняется при импорте пакета. Он может быть пустым или содержать код инициализации:

# mypackage/__init__.py
"""MyPackage — a utility library for data processing."""

__version__ = "1.0.0"
__author__ = "Developer"

# Re-export key classes for convenient access
from .models import User, Product
from .services import UserService

# Now users can do:
# from mypackage import User, UserService

Управление экспортом пакета

# mypackage/__init__.py
__all__ = ["User", "Product", "UserService"]

from .models import User, Product
from .services import UserService

# from mypackage import * — will only import User, Product, UserService

Namespace-пакеты (PEP 420)

Начиная с Python 3.3, директория без __init__.py может быть namespace-пакетом. Это позволяет распределять пакет по нескольким директориям:

# No __init__.py needed
# Python merges all directories with the same name
import mycompany.auth      # from path A
import mycompany.billing   # from path B
# Both work under the same namespace

На практике для обычных проектов всегда создавайте __init__.py.

Виртуальные окружения (venv)

Виртуальное окружение -- это изолированная копия Python-интерпретатора с собственным набором пакетов. Это решает проблему конфликтов зависимостей между проектами.

Создание и активация

# Create a virtual environment
python3 -m venv .venv

# Activate (macOS/Linux)
source .venv/bin/activate

# Activate (Windows)
.venv\Scripts\activate

# Deactivate when done
deactivate

Проверка активации

# Check which Python is active
which python
# /path/to/project/.venv/bin/python

# Check installed packages
pip list

Менеджер пакетов pip

pip -- стандартный менеджер пакетов Python, устанавливающий пакеты из PyPI (Python Package Index).

Основные команды

# Install a package
pip install requests

# Install specific version
pip install requests==2.31.0

# Install with version range
pip install "requests>=2.28,<3.0"

# Upgrade a package
pip install --upgrade requests

# Uninstall
pip uninstall requests

# Show package info
pip show requests

# List all installed packages
pip list

# List outdated packages
pip list --outdated

requirements.txt

Файл requirements.txt фиксирует зависимости проекта:

# Generate from current environment
pip freeze > requirements.txt

# Install all dependencies
pip install -r requirements.txt

Пример requirements.txt:

# requirements.txt — pinned versions for reproducibility
requests==2.31.0
pydantic==2.6.1
sqlalchemy==2.0.27
alembic==1.13.1
httpx==0.27.0

# Development dependencies (often in a separate file)
# requirements-dev.txt
pytest==8.0.2
mypy==1.8.0
ruff==0.3.0

Разделение зависимостей

# requirements.txt — production
requests==2.31.0
pydantic==2.6.1

# requirements-dev.txt — development
-r requirements.txt
pytest==8.0.2
mypy==1.8.0
ruff==0.3.0
black==24.2.0
# Install production deps
pip install -r requirements.txt

# Install all deps including dev
pip install -r requirements-dev.txt

pyproject.toml -- современный стандарт

pyproject.toml (PEP 518, PEP 621) -- единый файл конфигурации проекта, заменяющий setup.py, setup.cfg и requirements.txt:

# pyproject.toml
[project]
name = "myproject"
version = "1.0.0"
description = "A sample Python project"
requires-python = ">=3.12"
license = "MIT"
authors = [
    { name = "Developer", email = "[email protected]" }
]

dependencies = [
    "requests>=2.31",
    "pydantic>=2.6",
    "sqlalchemy>=2.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0",
    "mypy>=1.8",
    "ruff>=0.3",
]

[project.scripts]
myapp = "myproject.cli:main"

[build-system]
requires = ["setuptools>=70.0"]
build-backend = "setuptools.backends._legacy:_Backend"

uv -- быстрый менеджер пакетов

uv -- это современная замена pip и venv, написанная на Rust. Работает в 10-100 раз быстрее pip:

# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create a new project
uv init myproject
cd myproject

# Add dependencies
uv add requests pydantic

# Add dev dependencies
uv add --dev pytest mypy ruff

# Run a script
uv run python main.py

# Sync dependencies (install from lock file)
uv sync

# Create virtual environment explicitly
uv venv

uv.lock -- точная фиксация

uv автоматически создает uv.lock -- lock-файл с точными версиями всех зависимостей:

# uv.lock is created/updated automatically
uv add httpx

# Install exact versions from lock file
uv sync

# Update all dependencies
uv lock --upgrade

Структура проекта с uv

myproject/
    pyproject.toml     # Project configuration
    uv.lock            # Locked dependencies
    .venv/             # Virtual environment
    src/
        myproject/
            __init__.py
            main.py
    tests/
        test_main.py

pip-tools -- промежуточный вариант

pip-tools предоставляет компиляцию requirements:

pip install pip-tools

# Write loose requirements
# requirements.in
# requests>=2.31
# pydantic>=2.6

# Compile to pinned versions
pip-compile requirements.in

# Install pinned versions
pip-sync requirements.txt

Сравнение инструментов

Инструмент Скорость Lock-файл Управление venv pyproject.toml
pip + venv Медленно Нет Вручную Частично
pip-tools Медленно Да Вручную Нет
Poetry Средне Да Автоматически Да
uv Быстро Да Автоматически Да

Практический пример

Создадим проект с нуля используя uv:

# Initialize project
uv init webapp
cd webapp

# Add dependencies
uv add fastapi uvicorn[standard] pydantic

# Add dev dependencies
uv add --dev pytest httpx mypy ruff

# Project structure
# webapp/
#     pyproject.toml
#     uv.lock
#     src/
#         webapp/
#             __init__.py
# src/webapp/__init__.py
"""Web application package."""

__version__ = "0.1.0"
# src/webapp/main.py
from fastapi import FastAPI

app = FastAPI(title="WebApp", version="0.1.0")

@app.get("/health")
async def health() -> dict[str, str]:
    """Health check endpoint."""
    return {"status": "ok"}
# Run the application
uv run uvicorn webapp.main:app --reload

Проверь себя

Что делает команда pip freeze?

Какая команда создает виртуальное окружение в Python 3?

Какое преимущество uv перед pip?

Какой файл является современным стандартом конфигурации Python-проекта?

Для чего служит файл __init__.py в директории?