🐛 Типичные ошибки

⚡ Топ-3 ошибки

  • Забыть базовый случай рекурсии — получится бесконечный вызов и RecursionError.
  • Ловить всё подряд через «голый» except: — перехватываются системные исключения.
  • Проверять тип через type(x) == list вместо isinstance — код перестаёт поддерживать подклассы.

❌ Ошибка 1. Забытый базовый случай

def recursive_sum(numbers):
    # Missing base case and validation
    return numbers[0] + recursive_sum(numbers[1:])


print(recursive_sum([1, 2, 3]))  # RecursionError or IndexError

Почему плохо: без базового случая функция будет вызывать себя бесконечно, пока не закончится стек. Результат — RecursionError или IndexError.

✅ Исправление

def recursive_sum(numbers: list) -> float:
    if not isinstance(numbers, list):
        raise TypeError("Argument must be a list")
    if not numbers:
        return 0
    return numbers[0] + recursive_sum(numbers[1:])

❌ Ошибка 2. Проверка типа через type()

# Less flexible and does not support subclasses
def recursive_sum(numbers):
    if type(numbers) == list:
        return sum(numbers)
    raise TypeError("Not a list")

Почему плохо: type(x) == list не учитывает наследование и выглядит неидиоматично. isinstance поддерживает кортежи типов и подклассы.

✅ Исправление

def recursive_sum(numbers: list) -> float:
    if not isinstance(numbers, list):
        raise TypeError("Argument must be a list")
    ...

❌ Ошибка 3. «Голый» except

try:
    result = recursive_sum(data)
except:  # catches KeyboardInterrupt, SystemExit, etc.
    print("Ошибка")

Почему плохо: такой обработчик перехватывает KeyboardInterrupt, SystemExit и другие системные исключения, мешая нормальному завершению программы.

✅ Исправление

try:
    result = recursive_sum(data)
except TypeError as e:
    print(f"Ошибка типа: {e}")
except RecursionError as e:
    print(f"Слишком глубокая рекурсия: {e}")

❌ Ошибка 4. Подавление ошибки пустым pass

try:
    result = recursive_sum(data)
except TypeError:
    pass  # error is silently ignored

Почему плохо: программа не падает, но и не сообщает о проблеме. Отлаживать такой код крайне сложно.

✅ Исправление

try:
    result = recursive_sum(data)
except TypeError as e:
    print(f"Ошибка: {e}")

❌ Ошибка 5. Проверка аргумента после рекурсивного шага

def list_depth(nested_list):
    if not nested_list:
        return 1
    if isinstance(nested_list, list):
        return 1 + max(list_depth(item) for item in nested_list)
    raise TypeError("Not a list")

Почему плохо: валидация оказывается внутри рекурсии, поэтому нечисловые элементы или неверные типы обрабатываются поздно и неоднородно. Guard clause должна быть в начале функции.

✅ Исправление

def list_depth(nested_list: list) -> int:
    if not isinstance(nested_list, list):
        raise TypeError("Argument must be a list")
    ...