Данная инструкция предназначена для ИИ-ассистентов, которые проверяют код Python на соответствие общепринятым стандартам языка. Инструкция НЕ предполагает автоматическое исправление кода - только выявление проблем и предложение вариантов решения.
- НЕ исправляйте код автоматически - только указывайте на проблемы
- Предлагайте варианты решения - объясняйте, как можно исправить
- Запрашивайте согласие - перед любыми изменениями спрашивайте пользователя
- Будьте конструктивны - объясняйте почему что-то не соответствует стандартам
- Учитывайте контекст - некоторые отклонения могут быть оправданы
Проверяемые аспекты:
- Используются пробелы, а не табы (4 пробела на уровень отступа)
- Максимальная длина строки - 79 символов для кода, 72 для комментариев
- Пустые строки: 2 между функциями/классами верхнего уровня, 1 внутри классов
Тест:
# ❌ Плохо - табы или неправильное количество пробелов
def function():
return True # 2 пробела
# ❌ Плохо - строка слишком длинная
def very_long_function_name(argument1, argument2, argument3, argument4, argument5, argument6, argument7, argument8):
pass
# ✅ Хорошо
def function():
return True # 4 пробела
# ✅ Хорошо - перенос длинной строки
def very_long_function_name(
argument1, argument2, argument3,
argument4, argument5, argument6
):
passВывод для пользователя:
❌ Найдена проблема в строке 2:
Используется 2 пробела вместо 4 для отступа.
Рекомендация: Используйте 4 пробела на каждый уровень отступа согласно PEP 8.
Предложенное исправление:
def function():
return True
Исправить? (да/нет)
Проверяемые аспекты:
- Один пробел вокруг операторов присваивания и сравнения
- Один пробел после запятой
- Нет пробелов внутри скобок
- Нет пробелов перед двоеточием (кроме слайсов)
Тест:
# ❌ Плохо
x=1
y = 2+3
my_list = [ 1,2,3 ]
my_dict = {'key' : 'value'}
# ✅ Хорошо
x = 1
y = 2 + 3
my_list = [1, 2, 3]
my_dict = {'key': 'value'}Вывод для пользователя:
❌ Найдены проблемы с пробелами:
Строка 1: x=1
Отсутствуют пробелы вокруг оператора присваивания.
Должно быть: x = 1
Строка 2: y = 2+3
Отсутствуют пробелы вокруг оператора сложения.
Должно быть: y = 2 + 3
Строка 3: my_list = [ 1,2,3 ]
- Лишние пробелы внутри скобок
- Отсутствуют пробелы после запятых
Должно быть: my_list = [1, 2, 3]
Исправить все проблемы? (да/нет)
Проверяемые аспекты:
- Импорты в начале файла
- Группировка импортов: стандартная библиотека, сторонние пакеты, локальные модули
- Каждый импорт на отдельной строке (кроме
from module import a, b) - Абсолютные импорты предпочтительнее относительных
Тест:
# ❌ Плохо
import sys, os
from mypackage import *
# ✅ Хорошо
import os
import sys
from mypackage import module1, module2Вывод для пользователя:
❌ Проблемы с импортами:
Строка 1: import sys, os
Несколько импортов на одной строке.
Рекомендация: Разделите на отдельные строки:
import sys
import os
Строка 2: from mypackage import *
Используется wildcard import (*).
Проблема: Это загрязняет пространство имён и затрудняет понимание,
откуда берутся конкретные объекты.
Рекомендация: Явно перечислите импортируемые объекты:
from mypackage import SpecificClass, specific_function
Исправить? (да/нет)
Проверяемые аспекты:
- Переменные и функции:
snake_case - Классы:
PascalCase - Константы:
UPPER_SNAKE_CASE - Приватные атрибуты:
_leading_underscore - Имена не должны совпадать с встроенными функциями Python
Тест:
# ❌ Плохо
def MyFunction():
MyVariable = 5
return MyVariable
class my_class:
def __init__(self):
self.publicAttr = 1
# ✅ Хорошо
def my_function():
my_variable = 5
return my_variable
class MyClass:
def __init__(self):
self.public_attr = 1
self._private_attr = 2
MAX_SIZE = 100 # КонстантаВывод для пользователя:
❌ Проблемы с именованием:
Строка 2: def MyFunction():
Имя функции использует PascalCase вместо snake_case.
Должно быть: def my_function():
Строка 3: MyVariable = 5
Имя переменной использует PascalCase вместо snake_case.
Должно быть: my_variable = 5
Строка 6: class my_class:
Имя класса использует snake_case вместо PascalCase.
Должно быть: class MyClass:
Строка 8: self.publicAttr = 1
Имя атрибута использует camelCase вместо snake_case.
Должно быть: self.public_attr = 1
Исправить эти проблемы? (да/нет)
Проверяемые аспекты:
- Не переопределять встроенные функции (
list,dict,str,type,id, и т.д.) - Избегать одиночных букв
l,O,I(путаница с 1 и 0)
Тест:
# ❌ Плохо
list = [1, 2, 3]
dict = {'key': 'value'}
l = 10
O = 0
# ✅ Хорошо
items = [1, 2, 3]
mapping = {'key': 'value'}
length = 10
count = 0Вывод для пользователя:
⚠️ КРИТИЧЕСКАЯ ПРОБЛЕМА - Переопределение встроенных функций:
Строка 1: list = [1, 2, 3]
Переменная 'list' переопределяет встроенный тип list.
Проблема: После этого вы не сможете создавать списки через list().
Рекомендация: Используйте другое имя, например:
items = [1, 2, 3]
items_list = [1, 2, 3]
my_list = [1, 2, 3]
Строка 2: dict = {'key': 'value'}
Переменная 'dict' переопределяет встроенный тип dict.
Рекомендация: mapping = {'key': 'value'}
Строка 3: l = 10
Использование 'l' может привести к путанице с цифрой 1.
Рекомендация: length = 10
Исправить? (да/нет)
Проверяемые аспекты:
- Все публичные модули, классы, функции и методы должны иметь docstring
- Docstring заключается в тройные кавычки
""" - Однострочные docstring на одной строке
- Многострочные docstring: первая строка - краткое описание, затем пустая строка, затем детали
Тест:
# ❌ Плохо - отсутствует docstring
def calculate_sum(a, b):
return a + b
# ❌ Плохо - неправильное форматирование
def calculate_product(a, b):
"""Умножает два числа
и возвращает результат"""
return a * b
# ✅ Хорошо - однострочный docstring
def calculate_sum(a, b):
"""Возвращает сумму двух чисел."""
return a + b
# ✅ Хорошо - многострочный docstring
def complex_calculation(a, b, c):
"""
Выполняет сложное вычисление над тремя числами.
Args:
a (float): Первое число
b (float): Второе число
c (float): Третье число
Returns:
float: Результат вычисления
Raises:
ValueError: Если любой из аргументов отрицательный
"""
if a < 0 or b < 0 or c < 0:
raise ValueError("Все аргументы должны быть неотрицательными")
return (a + b) * cВывод для пользователя:
❌ Проблемы с документированием:
Строка 2: def calculate_sum(a, b):
Отсутствует docstring.
Рекомендация: Добавьте описание функции:
def calculate_sum(a, b):
"""Возвращает сумму двух чисел."""
return a + b
Строка 6-8: def calculate_product(a, b):
Неправильное форматирование многострочного docstring.
Проблема: Вторая строка должна быть пустой после краткого описания.
Рекомендация:
def calculate_product(a, b):
"""
Умножает два числа и возвращает результат.
Args:
a: Первое число
b: Второе число
Returns:
Произведение a и b
"""
return a * b
Добавить/исправить документацию? (да/нет)
Проверяемые аспекты:
- Функции не должны быть слишком длинными (рекомендация: до 50 строк)
- Избегать глубокой вложенности (более 3-4 уровней)
- Один уровень абстракции на функцию
Тест:
# ❌ Плохо - слишком много вложенности
def process_data(data):
for item in data:
if item is not None:
if item > 0:
if item % 2 == 0:
if item < 100:
print(item)
# ✅ Хорошо - упрощённая логика
def process_data(data):
for item in data:
if should_process_item(item):
print(item)
def should_process_item(item):
return (item is not None and
item > 0 and
item % 2 == 0 and
item < 100)Вывод для пользователя:
⚠️ Проблема со сложностью кода:
Строка 2-8: def process_data(data):
Обнаружена глубокая вложенность (5 уровней).
Проблема: Код трудно читать и тестировать.
Рекомендации:
1. Извлеките условия в отдельную функцию
2. Объедините условия через 'and'
3. Используйте ранний возврат (early return)
Пример рефакторинга:
def process_data(data):
for item in data:
if should_process_item(item):
print(item)
def should_process_item(item):
return (item is not None and
item > 0 and
item % 2 == 0 and
item < 100)
Выполнить рефакторинг? (да/нет)
Проверяемые аспекты:
- Ловить конкретные исключения, а не голый
except: - Не использовать исключения для управления потоком выполнения
- Предпочитать EAFP стилю LBYL (где уместно)
Тест:
# ❌ Плохо - слишком широкий except
try:
result = risky_operation()
except:
print("Что-то пошло не так")
# ❌ Плохо - исключения для управления потоком
try:
index = my_list.index(value)
found = True
except ValueError:
found = False
# ✅ Хорошо - конкретное исключение
try:
result = risky_operation()
except ValueError as e:
print(f"Ошибка значения: {e}")
except TypeError as e:
print(f"Ошибка типа: {e}")
# ✅ Хорошо - правильное использование
found = value in my_listВывод для пользователя:
❌ Проблемы с обработкой исключений:
Строка 2-4:
Используется голый except без указания типа исключения.
Проблема: Перехватываются все исключения, включая KeyboardInterrupt
и SystemExit, что может затруднить отладку.
Рекомендация:
try:
result = risky_operation()
except (ValueError, TypeError) as e:
print(f"Ошибка: {e}")
Строка 7-11:
Исключения используются для управления потоком выполнения.
Проблема: Это медленнее и менее читаемо.
Рекомендация:
found = value in my_list
Исправить? (да/нет)
Проверяемые аспекты:
- Использовать f-strings вместо конкатенации (Python 3.6+)
- Использовать метод
.format()или f-strings вместо% - Использовать тройные кавычки для многострочных строк
Тест:
# ❌ Плохо
name = "Иван"
age = 25
message = "Привет, " + name + "! Тебе " + str(age) + " лет."
message2 = "Привет, %s! Тебе %d лет." % (name, age)
# ✅ Хорошо
name = "Иван"
age = 25
message = f"Привет, {name}! Тебе {age} лет."Вывод для пользователя:
⚠️ Неэффективная работа со строками:
Строка 3:
Используется конкатенация строк через '+'.
Проблема: Менее читаемо и менее эффективно.
Рекомендация: Используйте f-strings:
message = f"Привет, {name}! Тебе {age} лет."
Строка 4:
Используется старый стиль форматирования через %.
Рекомендация: Используйте f-strings (Python 3.6+):
message2 = f"Привет, {name}! Тебе {age} лет."
Исправить? (да/нет)
Проверяемые аспекты:
- Использовать list/dict/set comprehensions где уместно
- Не изменять список во время итерации
- Использовать
enumerate()вместоrange(len()) - Использовать
zip()для параллельной итерации
Тест:
# ❌ Плохо
squares = []
for i in range(10):
squares.append(i ** 2)
# ❌ Плохо - изменение списка во время итерации
for item in my_list:
if condition(item):
my_list.remove(item)
# ❌ Плохо
for i in range(len(my_list)):
print(i, my_list[i])
# ✅ Хорошо
squares = [i ** 2 for i in range(10)]
# ✅ Хорошо
my_list = [item for item in my_list if not condition(item)]
# ✅ Хорошо
for i, item in enumerate(my_list):
print(i, item)Вывод для пользователя:
💡 Можно улучшить работу с коллекциями:
Строка 2-4:
Используется цикл для создания списка.
Рекомендация: Используйте list comprehension:
squares = [i ** 2 for i in range(10)]
Преимущество: Короче и быстрее.
Строка 7-9:
⚠️ ОПАСНО: Изменение списка во время итерации.
Проблема: Может привести к пропуску элементов или ошибкам.
Рекомендация:
my_list = [item for item in my_list if not condition(item)]
Строка 12-13:
Используется range(len()) для доступа к индексам.
Рекомендация: Используйте enumerate():
for i, item in enumerate(my_list):
print(i, item)
Применить улучшения? (да/нет)
Проверяемые аспекты:
- Использовать
withдля работы с файлами и ресурсами - Не забывать закрывать файлы и соединения
Тест:
# ❌ Плохо - файл может не закрыться при ошибке
f = open('file.txt', 'r')
data = f.read()
f.close()
# ✅ Хорошо
with open('file.txt', 'r') as f:
data = f.read()Вывод для пользователя:
⚠️ Небезопасная работа с ресурсами:
Строка 2-4:
Файл открывается без использования контекстного менеджера.
Проблема: Если произойдёт ошибка между open() и close(),
файл останется открытым (утечка ресурсов).
Рекомендация: Используйте оператор with:
with open('file.txt', 'r') as f:
data = f.read()
Преимущество: Файл автоматически закроется даже при ошибке.
Исправить? (да/нет)
Проверяемые аспекты:
- Использование type hints для параметров и возвращаемых значений
- Использование
typingмодуля для сложных типов
Тест:
# ❌ Без типов
def calculate(a, b):
return a + b
# ✅ С типами
def calculate(a: int, b: int) -> int:
return a + b
# ✅ Сложные типы
from typing import List, Dict, Optional
def process_data(items: List[int]) -> Dict[str, int]:
return {"sum": sum(items), "count": len(items)}
def find_user(user_id: int) -> Optional[str]:
# Может вернуть None
return user_name if user_exists else NoneВывод для пользователя:
💡 Рекомендация: Добавить аннотации типов
Строка 2: def calculate(a, b):
Отсутствуют аннотации типов.
Рекомендация: Добавьте type hints:
def calculate(a: int, b: int) -> int:
return a + b
Преимущества:
- Улучшает читаемость кода
- Позволяет IDE предоставлять лучшие подсказки
- Помогает находить ошибки на ранних этапах
Примечание: Это не строгое требование PEP 8, но рекомендуемая
практика для современного Python кода.
Добавить type hints? (да/нет)
- Проверить порядок импортов
- Проверить наличие docstring модуля
- Проверить структуру: импорты → константы → классы/функции
- Проверить отступы (4 пробела)
- Проверить длину строк (≤79 символов)
- Проверить пустые строки между определениями
- Проверить пробелы вокруг операторов
- Проверить имена функций (snake_case)
- Проверить имена классов (PascalCase)
- Проверить имена переменных (snake_case)
- Проверить константы (UPPER_SNAKE_CASE)
- Проверить, не переопределены ли встроенные функции
- Проверить наличие docstrings у функций/классов
- Проверить формат docstrings
- Проверить полноту документации (параметры, возвращаемые значения)
- Проверить сложность функций
- Проверить глубину вложенности
- Проверить обработку исключений
- Проверить использование best practices
Структура отчёта:
═══════════════════════════════════════════════════════════
ОТЧЁТ О ПРОВЕРКЕ КОДА PYTHON
═══════════════════════════════════════════════════════════
Файл: example.py
Дата проверки: [ДАТА]
Количество строк: [N]
───────────────────────────────────────────────────────────
СВОДКА
───────────────────────────────────────────────────────────
✓ Критических проблем: [N]
⚠ Предупреждений: [N]
💡 Рекомендаций: [N]
───────────────────────────────────────────────────────────
КРИТИЧЕСКИЕ ПРОБЛЕМЫ
───────────────────────────────────────────────────────────
[Список критических проблем с предложениями по исправлению]
───────────────────────────────────────────────────────────
ПРЕДУПРЕЖДЕНИЯ
───────────────────────────────────────────────────────────
[Список предупреждений с предложениями по исправлению]
───────────────────────────────────────────────────────────
РЕКОМЕНДАЦИИ
───────────────────────────────────────────────────────────
[Список рекомендаций по улучшению]
───────────────────────────────────────────────────────────
ЗАКЛЮЧЕНИЕ
───────────────────────────────────────────────────────────
[Общая оценка качества кода и приоритетные действия]
═══════════════════════════════════════════════════════════
❌ Найдена проблема в строке 15:
def MyFunction():
pass
Проблема: Имя функции использует PascalCase вместо snake_case.
Стандарт: PEP 8 требует использования snake_case для имён функций.
Предложенное исправление:
def my_function():
pass
Хотите, чтобы я исправил эту проблему? (да/нет)
Найдено 3 проблемы в файле example.py:
1. ❌ Строка 5: Переопределение встроенной функции
list = [1, 2, 3]
→ Рекомендуется: items = [1, 2, 3]
2. ⚠️ Строка 12: Отсутствует docstring
def calculate():
→ Добавьте описание функции
3. 💡 Строка 20: Можно использовать f-string
msg = "Hello " + name
→ Рекомендуется: msg = f"Hello {name}"
Хотите исправить:
a) Все проблемы
b) Только критические (пункт 1)
c) Выборочно (я спрошу по каждой)
d) Не исправлять сейчас
Ваш выбор: _
⚠️ Обнаружена короткая функция без docstring:
def add(a, b):
return a + b
Вопрос: Это служебная/приватная функция или часть публичного API?
- Если публичная API: рекомендуется добавить docstring
- Если приватная: можно оставить без docstring, но переименовать в _add()
Как поступить? (добавить docstring / переименовать / оставить как есть)
- Переопределение встроенных функций
- Синтаксические ошибки в соответствии со стандартами
- Небезопасные практики (например, изменение списка во время итерации)
- Голые
except:блоки
- Неправильное именование
- Отсутствие docstrings у публичных функций/классов
- Нарушения форматирования (длина строк, отступы)
- Неправильная структура импортов
- Слишком сложные функции
- Использование устаревших конструкций (% форматирование)
- Отсутствие type hints
- Возможности использования comprehensions
- Упрощение логики кода
Перед отправкой отчёта убедитесь, что вы:
- Проверили все аспекты из разделов 1-6
- Сгруппировали проблемы по категориям (критические/предупреждения/рекомендации)
- Для каждой проблемы указали:
- Номер строки
- Суть проблемы
- Почему это проблема (стандарт/best practice)
- Конкретное предложение по исправлению
- Пример правильного кода
- НЕ внесли изменения автоматически
- Задали чёткий вопрос пользователю о дальнейших действиях
- Использовали понятный и конструктивный тон
Рекомендуйте пользователю следующие инструменты:
-
flake8 - проверка на соответствие PEP 8
pip install flake8 flake8 your_file.py
-
pylint - более строгий линтер
pip install pylint pylint your_file.py
-
black - автоматическое форматирование
pip install black black your_file.py --check # только проверка -
mypy - проверка типов
pip install mypy mypy your_file.py
-
isort - сортировка импортов
pip install isort isort your_file.py --check-only # только проверка
Следуйте этой инструкции последовательно для каждого файла Python. Будьте внимательны, конструктивны и всегда спрашивайте разрешения перед внесением изменений. Ваша цель - помочь разработчику писать чистый, читаемый и соответствующий стандартам код.
Помните: Стандарты существуют для улучшения качества кода, но иногда обоснованные отклонения допустимы. Всегда учитывайте контекст и спрашивайте, если не уверены.