Оберните метод функцией с *args и **kwargs, выведите func.name и верните результат вызова. self передастся как обычный первый аргумент.
Декоратор @trace, выводящий сообщение о начале вызова метода
Оберните метод функцией с *args и **kwargs, выведите func.__name__ и верните результат вызова. self передастся как обычный первый аргумент.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Создайте декоратор @trace, который при каждом вызове метода любого экземпляра класса Person будет писать в стандартный вывод строку вида: Entering function <имя_метода>
Пример поведения:
- при вызове метода speak() должно появиться сообщение: Entering function speak
- при вызове метода walk() — Entering function walk
class Person:
def __init__(self, person_name):
self.person_name = person_name
self.total_distance = 0
@trace
def speak(self, sentence):
print(f'{self.person_name}: "{sentence}"')
@trace
def walk(self, distance):
self.total_distance += distance
print(f'{self.person_name}: total distance is {self.total_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, затем вывод исходного метода. walk аналогично сохранит обновление total_distance. Декоратор нужно определить или импортировать до объявления класса Person.
wraps сохраняет имя, документацию и ссылку на исходную функцию. Состояние экземпляра не хранится в декораторе, поэтому разные объекты Person продолжают работать независимо.