Перейти к содержимому

10. Модули и пакеты

Иллюстрация к уроку

# Импорт модуля
import math
math.sqrt(16) # 4.0
# Импорт конкретных имён
from math import sqrt, pi, ceil
# Импорт с псевдонимом
import numpy as np
from datetime import datetime as dt
# Импорт всего (не рекомендуем — засоряет пространство имён)
from math import *

Python “batteries included” — богатая стандартная библиотека:

# os — работа с операционной системой
import os
os.getcwd() # текущая директория
os.listdir(".") # список файлов
os.path.join("dir", "file.txt") # путь
os.path.exists("/path/file") # существует ли
os.environ.get("HOME") # переменные окружения
os.makedirs("new/dir", exist_ok=True) # создать директорию
# pathlib — современный способ работы с путями
from pathlib import Path
p = Path(".")
p.cwd() # текущая директория
p.home() # домашняя директория
(p / "subdir" / "file.txt").exists()
list(p.glob("*.py")) # все .py файлы
config = Path("config.json")
text = config.read_text(encoding="utf-8")
config.write_text('{"key": "value"}')
# json
import json
data = {"name": "Яша", "age": 2, "tags": ["ai", "python"]}
json_str = json.dumps(data, ensure_ascii=False, indent=2)
parsed = json.loads(json_str)
# Чтение/запись файлов
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open("data.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
# datetime
from datetime import datetime, date, timedelta, timezone
now = datetime.now()
utc_now = datetime.now(timezone.utc)
today = date.today()
tomorrow = today + timedelta(days=1)
# Форматирование
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
parsed_date = datetime.strptime("2024-01-15", "%Y-%m-%d")
# ISO format (для API)
now.isoformat() # "2024-01-15T10:30:00.000000"
# re — регулярные выражения
import re
pattern = r"\b\d{3}-\d{4}\b" # телефон xxx-xxxx
text = "Звони: 123-4567 или 987-6543"
matches = re.findall(pattern, text) # ["123-4567", "987-6543"]
email_pattern = r"[\w.+-]+@[\w-]+\.[a-z]{2,}"
cleaned = re.sub(r"\s+", " ", "слишком много пробелов")
# random
import random
random.random() # 0.0 до 1.0
random.randint(1, 10) # целое от 1 до 10
random.choice([1, 2, 3]) # случайный элемент
random.shuffle([1, 2, 3]) # перемешать на месте
random.sample([1,2,3,4,5], 3) # 3 уникальных элемента
# secrets — для криптографии (лучше random для паролей!)
import secrets
secrets.token_hex(32) # "a3f2b1c9..."
secrets.token_urlsafe() # URL-safe строка
utils/string_utils.py
def slugify(text: str) -> str:
"""Конвертирует текст в slug."""
import re
text = text.lower()
text = re.sub(r"[^\w\s-]", "", text)
text = re.sub(r"[\s_-]+", "-", text)
return text.strip("-")
def truncate(text: str, max_length: int = 100) -> str:
"""Обрезает текст с многоточием."""
if len(text) <= max_length:
return text
return text[:max_length - 3] + "..."
# Использование
from utils.string_utils import slugify, truncate
slugify("Hello World!") # "hello-world"
truncate("Длинный текст", 10) # "Длинный..."
my_package/
├── __init__.py # делает директорию пакетом
├── core.py
├── utils/
│ ├── __init__.py
│ ├── string_utils.py
│ └── date_utils.py
└── models/
├── __init__.py
├── user.py
└── product.py
my_package/__init__.py
from .core import main_function
from .models.user import User
__version__ = "1.0.0"
__all__ = ["main_function", "User"]
Окно терминала
pip install httpx pydantic python-dotenv loguru rich
# httpx — HTTP клиент (как axios в JS)
import httpx
# Синхронный
response = httpx.get("https://api.github.com/users/octocat")
data = response.json()
# Асинхронный
async with httpx.AsyncClient() as client:
response = await client.get("https://api.example.com/data")
# pydantic — валидация данных
from pydantic import BaseModel, EmailStr, Field
class UserCreate(BaseModel):
name: str = Field(min_length=1, max_length=50)
email: EmailStr
age: int = Field(ge=0, le=150)
role: str = "user"
user = UserCreate(name="Яша", email="[email protected]", age=2)
# Автоматическая валидация! ValueError если неверные данные
# python-dotenv — переменные окружения
from dotenv import load_dotenv
import os
load_dotenv() # читает .env файл
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./test.db")
# loguru — красивые логи
from loguru import logger
logger.info("Сервер запущен")
logger.warning("Внимание!")
logger.error("Произошла ошибка")
logger.debug("Отладочная информация")
# rich — красивый вывод в терминале
from rich import print
from rich.table import Table
from rich.console import Console
console = Console()
console.print("[bold green]Success![/bold green]")
table = Table(title="Пользователи")
table.add_column("Имя")
table.add_column("Роль")
table.add_row("Яша", "[red]admin[/red]")
console.print(table)
script.py
def main():
print("Запущен как скрипт")
def helper():
return "полезная функция"
# Этот блок выполняется ТОЛЬКО при прямом запуске
# Не выполняется при import!
if __name__ == "__main__":
main()
Окно терминала
python3 script.py # выполнит main()
# vs
python3 -c "from script import helper; print(helper())" # main() не выполнится
# Задание 1: Создай пакет `validators` со следующими функциями:
# - validate_email(email: str) -> bool
# - validate_phone(phone: str) -> bool (формат: +7XXXXXXXXXX)
# - validate_password(password: str) -> list[str] # список ошибок
# Требования: мин 8 символов, заглавная буква, цифра, спецсимвол
# Задание 2: Создай модуль `config.py` который:
# - Читает .env файл
# - Предоставляет typed конфигурацию (dataclass или pydantic)
# - Валидирует обязательные поля
# - Поддерживает дефолтные значения

В следующем уроке — работа с файлами!