Ответ 1
Для вашего конкретного примера вы можете написать
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
.