Как сделать функцию композитора - PullRequest
0 голосов
/ 07 ноября 2018

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

def rounding(funct):
    return round(funct)

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

EDIT: функция должна иметь только один параметр. Например начало функции должно быть

def rounding(func):

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

Ответы [ 3 ]

0 голосов
/ 07 ноября 2018

Для вашего конкретного примера вы можете написать

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.

0 голосов
/ 07 ноября 2018

Композиция функций изначально не поддерживается в Python. Вы можете использовать декоратор согласно @ решению Алекса . Вы можете явно определить новую функцию в соответствии с решением @ 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
0 голосов
/ 07 ноября 2018

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

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 ) которые вы можете найти, погуглив эти термины.
...