Для вашего конкретного примера вы можете написать
def round_sqrt(x):
return round(sqrt(x))
ответ Алекса обобщает это; он определяет функцию, которую создает round_sqrt
для вас. Если функция уже определена, вы просто передаете ее в качестве аргумента rounder
:
round_sqrt = rounder(sqrt)
Конечно, вам не нужно определять round_sqrt
, если вы не хотите. rounder(sqrt)(3.2)
можно вызвать напрямую, хотя гораздо эффективнее сохранить возвращаемое значение rounder
, если вы собираетесь использовать его несколько раз, а не переопределять его каждый раз.
В противном случае синтаксис декоратора просто короток (на примере Алекса)
def adder(x, y):
return x + y
adder = rounder(adder)
Как я уже сказал в своем комментарии, это пример реализации композиции. Математически состав прост, потому что математические функции всегда принимают один аргумент и возвращают один аргумент. Таким образом, состав двух функций f
и g
всегда можно определить просто как
def compose(f, g):
def h(x): # The name doesn't matter
return f(g(x))
return h
Тогда
round_sqrt = compose(round, sqrt)
(Игнорируя всевозможные практические проблемы, связанные с реализацией, Python теоретически может даже обеспечить оператор Unicode ∘
для функций: round_sqrt = round ∘ sort
. Объяснение , почему этого не произойдет, выходит за рамки этого ответа.)
Однако в Python функции намного сложнее. Они могут принимать несколько аргументов, они могут принимать произвольное количество аргументов и произвольных аргументов ключевого слова, и хотя каждый из них технически возвращает одно значение, это значение может быть кортежем, который рассматривается как несколько значений, или dict
. В результате может быть много способов передать возвращаемое значение g
в функцию f
, что гораздо проще, чем с помощью простой функции compose
.