Оберните метод функцией с *args/**kwargs, напечатайте func.name и верните результат оригинала. self будет обычным первым аргументом, поэтому декоратор подходит разным классам.
Декоратор, выводящий сообщение при вызове метода
Оберните метод функцией с *args/**kwargs, напечатайте func.__name__ и верните результат оригинала. self будет обычным первым аргументом, поэтому декоратор подходит разным классам.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо реализовать декоратор @trace, который при каждом вызове метода любого класса выводит строку вида "Entering function <имя_метода>". Например, при вызове метода speak() должно появиться сообщение "Entering function speak", а при вызове метода walk() — "Entering function walk".
class Person:
def __init__(self, name):
self.name = name
self.distance = 0
@trace
def speak(self, sentence):
print(f'{self.name}: "{sentence}"')
@trace
def walk(self, distance):
self.distance += distance
print(f'{self.name}: total distance is {self.distance} meters')
Ответ
Оберните метод функцией с *args/**kwargs, напечатайте func.name и верните результат оригинала. self будет обычным первым аргументом, поэтому декоратор подходит разным классам.
Декоратор нужно определить до использования класса:
from functools import wraps
def trace(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f'Entering function {func.__name__}')
return func(*args, **kwargs)
return wrapper
Вызов person.speak('Hello') сначала печатает Entering function speak, затем выполняет тело метода. Возвращаемое значение и исключения не теряются. wraps сохраняет метаданные, что важно для отладки и инструментов интроспекции. Содержимое аргументов выводить не требуется.