Рефакторинг: улучшаем код с помощью ИИ
Рефакторинг — это улучшение кода без изменения его поведения. Убираешь дублирование, делаешь код чище, понятнее, надёжнее. ИИ делает это хорошо — особенно если дать правильный контекст.
Когда рефакторить
- Код разросся и стало сложно вносить изменения
- Одно и то же написано в нескольких местах
- Функция делает слишком много всего
- Имена переменных ни о чём не говорят
- Добавить новую фичу требует правок в 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)
[вставь код]Практические примеры
До: процедурный спагетти-код
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")После: чистый, понятный код
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 для следующей проблемыАвтоматическая проверка качества кода
# Установить
pip install flake8 black isort mypy
# Форматирование (автоматически правит код)
black .
# Сортировка импортов
isort .
# Линтер (показывает проблемы)
flake8 . --max-line-length=100
# Проверка типов
mypy main.pyПопроси ИИ исправить конкретные ошибки flake8:
Вот вывод flake8:
[вставь вывод]
Исправь эти ошибки в коде:
[вставь код]Когда НЕ рефакторить
- Код работает и больше не меняется — не трогай
- Нет времени — добавь TODO-комментарий и идёшь дальше
- Нет тестов и функция критичная — сначала тесты
Лучший рефакторинг — тот, который не нужен, потому что код был написан чисто с начала. Для этого: хороший CLAUDE.md, понятные промпты ИИ, маленькие шаги.
Что дальше?
После рефакторинга — добавь тесты чтобы убедиться что ничего не сломалось, и защити код от деградации в будущем.