Как сделать функцию композитора - программирование
Подтвердить что ты не робот

Как сделать функцию композитора

Я пытаюсь сделать функцию, которая округляет другие функции для моего университетского диплома. Например, я хотел бы вызвать round_sqrt = round(sqrt) и когда я вызываю round_sqrt(5) он должен показать мне 2 вместо 2.23606797749979. Что я пытаюсь это:

def rounding(funct):
    return round(funct)

но это не работает

РЕДАКТИРОВАТЬ: функция должна иметь только один параметр. Например, начало функции должно быть

def rounding(func):

так что в этой функции funct функция должна быть округлена. поэтому, когда я вызываю rounding(abs)(3.2) оно показывает мне 3.

4b9b3361

Ответ 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.

Ответ 2

Вы должны проверить закрытия:

def rounder(func):
    def inner(*args, **kwargs):
        return round(func(*args, **kwargs))
    return inner

Затем вы можете украсить функции, используя символ @:

@rounder
def adder(x, y):
    return x + y

print(adder(1.1, 2.2))

выходы 3

Дополнительно:

  1. Вы можете использовать functools.wraps в своем закрытии, чтобы не потерять информацию (например, строку документации, имя функции) об исходной функции.
  2. Существует множество ресурсов для изучения замыканий (например, 1, 2) и декораторов (например, 1, 2), которые вы можете найти с помощью Google Googling.

Ответ 3

Композиция функций изначально не поддерживается в Python. Вы можете использовать декоратор согласно решению @Alex. Вы можете явно определить новую функцию согласно решению @chepner.

Или вы можете использовать стороннюю библиотеку. Например, через toolz.compose:

from toolz import compose

def adder(x, y):
    return x + y

round_adder = compose(round, adder)

round_adder(1.1, 2.2)  # 3