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

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

  1. Забыть вернуть результат из обёртки декоратора.
  2. Не использовать @functools.wraps и потерять метаданные.
  3. В декораторе-фабрике забыть вызвать декорируемую функцию.
  4. Забыть self в методах класса.
  5. Перепутать класс и объект (book = Book вместо book = Book(...)).

❌ Ошибка 1. Потеря результата в декораторе

def upper_decorator(func):
    def wrapper(*args, **kwargs):
        print("Выполняем функцию")
        func(*args, **kwargs).upper()  # результат не возвращается
    return wrapper

Почему возникает: результат вызова func обрабатывается, но не возвращается из wrapper. Декорированная функция возвращает None.

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

def upper_decorator(func):
    def wrapper(*args, **kwargs):
        print("Выполняем функцию")
        return func(*args, **kwargs).upper()
    return wrapper

❌ Ошибка 2. Потеря метаданных без functools.wraps

def decorator(func):
    def wrapper():
        return func()
    return wrapper


@decorator
def hello():
    """Say hello."""
    print("Hello")


print(hello.__name__)  # wrapper
print(hello.__doc__)   # None

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

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

import functools


def decorator(func):
    @functools.wraps(func)
    def wrapper():
        return func()
    return wrapper

❌ Ошибка 3. Декоратор не вызывает функцию

def decorator(func):
    def wrapper(*args, **kwargs):
        print("Ошибка")
        return func  # забыли скобки
    return wrapper

Почему возникает: return func возвращает сам объект функции, а не результат её работы.

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

def decorator(func):
    def wrapper(*args, **kwargs):
        print("Ошибка")
        return func(*args, **kwargs)
    return wrapper

❌ Ошибка 4. Забыт self в методе

class Person:
    def __init__(name, age):  # пропущен self
        self.name = name
        self.age = age

Сообщение об ошибке: при создании объекта возникнет TypeError, потому что Python передаст self в первый параметр name.

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

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

❌ Ошибка 5. Класс вместо объекта

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author


book = Book
print(book.title)  # AttributeError

Почему возникает: Book без скобок — это ссылка на класс, а не созданный объект.

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

book = Book("1984", "George Orwell")
print(book.title)

❌ Ошибка 6. Ожидание, что изменение одного объекта повлияет на другие

class Book:
    def __init__(self, title):
        self.title = title


book1 = Book("1984")
book2 = Book("Brave New World")
book1.title = "Animal Farm"
print(book2.title)  # всё ещё Brave New World

Почему возникает: каждый объект — независимый экземпляр. Поля одного объекта не связаны с полями другого.