Skip to content

Рефакторинг: улучшаем код с помощью ИИ

Рефакторинг — это улучшение кода без изменения его поведения. Убираешь дублирование, делаешь код чище, понятнее, надёжнее. ИИ делает это хорошо — особенно если дать правильный контекст.

Когда рефакторить

  • Код разросся и стало сложно вносить изменения
  • Одно и то же написано в нескольких местах
  • Функция делает слишком много всего
  • Имена переменных ни о чём не говорят
  • Добавить новую фичу требует правок в 5 разных местах

Главные правила

1. Работает → сначала тесты Прежде чем рефакторить — убедись что есть тесты или ручная проверка. После рефакторинга должно работать так же.

2. Мелкие шаги Не пытайся переписать всё сразу. Один файл, один класс, одна функция — коммит — следующий шаг.

3. Не рефакторь попутно Если правишь баг — не рефакторь код рядом. Если добавляешь фичу — не рефакторь. Отдельная задача — отдельный коммит.

Промпты для рефакторинга

Улучшить читаемость

Отрефакторь этот код.
Задача: улучшить читаемость, не меняя поведение.
Что хочу:
- Понятные имена переменных (на английском, описательные)
- Разбить длинные функции на маленькие с говорящими именами
- Убрать дублирование
- Добавить type hints

Поведение не должно измениться.
Объясни каждое значимое изменение.

[вставь код]

Убрать дублирование

В этом коде одно и то же написано в нескольких местах.
Выдели повторяющуюся логику в отдельную функцию/метод.
Объясни что вынес и почему.

[вставь код с дублированием]

Разбить большую функцию

Эта функция делает слишком много.
Разбей её на несколько с говорящими именами.
Каждая должна делать одно дело.
Основная функция должна читаться как план:
шаг1(), шаг2(), шаг3() — без деталей реализации.

[вставь большую функцию]

Добавить типы

Добавь type hints во весь код.
Используй современный синтаксис Python 3.10+:
- str | None вместо Optional[str]
- list[str] вместо List[str]
- dict[str, int] вместо Dict[str, int]
Ничего не переписывай кроме аннотаций.

[вставь код]

Обработка ошибок

Добавь правильную обработку ошибок в этот код.
Что нужно:
- try/except на опасные операции (сеть, файлы, внешние API)
- логировать ошибки через logging, не print
- функции должны возвращать внятные сообщения об ошибках
- не проглатывать исключения молча (except: pass)

[вставь код]

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

До: процедурный спагетти-код

python
def process():
    data = []
    with open("input.csv") as f:
        for line in f:
            parts = line.strip().split(",")
            if len(parts) >= 3:
                name = parts[0].strip()
                email = parts[1].strip()
                age = int(parts[2].strip())
                if age > 18 and "@" in email:
                    data.append({"name": name, "email": email, "age": age})
    
    result = []
    for item in data:
        n = item["name"]
        e = item["email"]
        a = item["age"]
        msg = f"Уважаемый(ая) {n},\n\nВаш аккаунт {e} активирован. Вам {a} лет."
        result.append(msg)
    
    for msg in result:
        with open("output.txt", "a") as f:
            f.write(msg + "\n\n")

После: чистый, понятный код

python
from dataclasses import dataclass
from pathlib import Path

@dataclass
class User:
    name: str
    email: str
    age: int

def load_users(csv_path: str) -> list[User]:
    users = []
    with open(csv_path, encoding="utf-8") as f:
        for line in f:
            parts = line.strip().split(",")
            if len(parts) < 3:
                continue
            name, email, age_str = parts[0].strip(), parts[1].strip(), parts[2].strip()
            try:
                age = int(age_str)
            except ValueError:
                continue
            if is_valid_user(age, email):
                users.append(User(name=name, email=email, age=age))
    return users

def is_valid_user(age: int, email: str) -> bool:
    return age > 18 and "@" in email

def format_welcome_message(user: User) -> str:
    return (
        f"Уважаемый(ая) {user.name},\n\n"
        f"Ваш аккаунт {user.email} активирован. Вам {user.age} лет."
    )

def save_messages(messages: list[str], output_path: str) -> None:
    Path(output_path).write_text("\n\n".join(messages), encoding="utf-8")

def process(input_csv: str = "input.csv", output_txt: str = "output.txt") -> None:
    users = load_users(input_csv)
    messages = [format_welcome_message(user) for user in users]
    save_messages(messages, output_txt)
    print(f"Обработано {len(users)} пользователей")

Разница:

  • Каждая функция делает одно дело
  • Имена говорят что происходит
  • Данные в dataclass — не голые словари
  • Легко тестировать каждую функцию отдельно

Последовательность рефакторинга большого файла

Шаг 1: Попроси ИИ оценить код
"Прочитай этот файл и скажи:
- Какие главные проблемы?
- С чего начать рефакторинг?
- Что НЕ трогать сейчас?"

Шаг 2: Исправь самое критичное
"Исправь только [конкретную проблему из шага 1].
Остальное пока не трогай."

Шаг 3: Проверь что работает
# запусти тесты или проверь вручную

Шаг 4: Коммит
git add . && git commit -m "refactor: ..."

Шаг 5: Следующая проблема
Повтори шаги 2-4 для следующей проблемы

Автоматическая проверка качества кода

bash
# Установить
pip install flake8 black isort mypy

# Форматирование (автоматически правит код)
black .

# Сортировка импортов
isort .

# Линтер (показывает проблемы)
flake8 . --max-line-length=100

# Проверка типов
mypy main.py

Попроси ИИ исправить конкретные ошибки flake8:

Вот вывод flake8:
[вставь вывод]

Исправь эти ошибки в коде:
[вставь код]

Когда НЕ рефакторить

  • Код работает и больше не меняется — не трогай
  • Нет времени — добавь TODO-комментарий и идёшь дальше
  • Нет тестов и функция критичная — сначала тесты

Лучший рефакторинг — тот, который не нужен, потому что код был написан чисто с начала. Для этого: хороший CLAUDE.md, понятные промпты ИИ, маленькие шаги.


Что дальше?

После рефакторинга — добавь тесты чтобы убедиться что ничего не сломалось, и защити код от деградации в будущем.