Вопрос проверяет знание метаданных функции и практику корректного написания декораторов.
Имя функции доступно через атрибут func.__name__. Внутри декоратора можно использовать его, например, для логирования. Однако после оборачивания имя функции может замениться на имя wrapper. Чтобы сохранить оригинальные метаданные, используют functools.wraps.
Каждая функция в Python — это объект, у которого есть атрибуты, включая имя.
Определение: __name__ — атрибут функции, содержащий её имя.
def log_calls(func):
def wrapper(*args, **kwargs):
print("Вызов функции:", func.__name__)
return func(*args, **kwargs)
return wrapper
Если использовать такой декоратор:
@log_calls
def process():
pass
print(process.__name__) # wrapper
Имя оригинальной функции теряется.
Используется functools.wraps:
from functools import wraps
def log_calls(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("Вызов функции:", func.__name__)
return func(*args, **kwargs)
return wrapper
Теперь:
print(process.__name__) # process
логирование;
трассировка вызовов;
документация и introspection;
инструменты тестирования.
Имя функции можно получить через func.__name__, но для корректной работы декораторов нужно использовать functools.wraps, чтобы сохранить метаданные функции.