MiddleКодИногдаЕщё не отвечали
Стек декораторов add_tag('h1') над add_div — реализация и порядок
Реализуйте add_div и параметризованный add_tag(tag), оборачивающие возвращаемую строку. @add_div даёт <div>...</div>; стек @add_tag('h1') над @add_div даёт <h1><div>...</div></h1>.
Требования:
- Оборачивайте возвращённую строку; сохраняйте метаданные через
functools.wraps. - Объясните, почему нижний декоратор применяется первым.
def add_div(func):
# ваш код здесь
Допишите реализацию.
add_div оборачивает результат func в <div>...</div>. add_tag(tag) — фабрика: берёт тег и возвращает декоратор, оборачивающий результат в <tag>...</tag>. Стек декораторов применяется снизу вверх — сначала @add_div, затем @add_tag('h1') оборачивает его — поэтому внутренняя разметка это div, а внешняя h1, давая <h1><div>...</div></h1>. Используйте @wraps на каждой обёртке.
- ✗Переворачивать порядок применения, получая
<div><h1>...</h1></div> - ✗Писать
add_tagбез дополнительного слоя-фабрики для аргумента - ✗Забывать
@wraps, теряя метаданные декорируемой функции
- →Почему декоратор ближайший к функции (нижний) срабатывает первым?
- →Как определить
add_divкакadd_tag('div'), чтобы убрать дублирование?
Оглавление
Задача
Реализуйте add_div и add_tag(tag), оборачивающие строковый результат; объясните порядок применения стека декораторов.
Решение
from functools import wraps
def add_div(func):
@wraps(func)
def wrapper(*args, **kwargs):
return f"<div>{func(*args, **kwargs)}</div>"
return wrapper
def add_tag(tag):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
return f"<{tag}>{func(*args, **kwargs)}</{tag}>"
return wrapper
return decorator
@add_tag('h1')
@add_div
def greeting(name):
return f"Hello, {name}!"
# greeting("Mary") -> "<h1><div>Hello, Mary!</div></h1>"
Ключевые моменты
- Стек применяется снизу вверх:
add_divпервым, затемadd_tag('h1')поверх. add_tag— фабрика (три уровня), ведь принимает аргументtag.@wrapsна каждой обёртке сохраняет имя и докстрингgreeting.
Оглавление