композиция функций VS функция, которая действует на другую функцию - PullRequest
0 голосов
/ 25 января 2012

У меня есть множество функций многократного использования, все с одной и той же сигнатурой (они принимают record и возвращают float).Мне часто нужно объединить функции в новую функцию.

Допустим, я хочу создать функцию, которая принимает record, применяет к ней f и, если результат отрицательный, преобразует ее в ноль.У меня есть два способа сделать это: изменение состава и функции.Каковы плюсы и минусы каждого подхода?

Состав:

def non_negative(value):
    return max(0, value)

g = compose(non_negative, f)

# from functional module by Collin Winter
def compose(func_1, func_2, unpack=False):
    """
    compose(func_1, func_2, unpack=False) -> function

    The function returned by compose is a composition of func_1 and func_2.
    That is, compose(func_1, func_2)(5) == func_1(func_2(5))
    """
    if not callable(func_1):
        raise TypeError("First argument to compose must be callable")
    if not callable(func_2):
        raise TypeError("Second argument to compose must be callable")

    if unpack:
        def composition(*args, **kwargs):
            return func_1(*func_2(*args, **kwargs))
    else:
        def composition(*args, **kwargs):
            return func_1(func_2(*args, **kwargs))
    return composition

Модификация:

def non_negative(func):
    def new_func(record):
        return max(0, func(record))
    return new_func

g = non_negative(f)    

Ответы [ 2 ]

2 голосов
/ 26 января 2012

Предполагая, что compose доступно в библиотеке, я бы предпочел этот стиль для этого примера.

Основная причина состоит в том, что он разделяет задачи фиксирования значения на неотрицательные значения и передачи результата одной функции в другую. В стиле «модификации», если вы когда-нибудь захотите запустить non_negative для значения, а не для результата функции, вы получите в результате искажения типа non_negative(lambda x: x)(value). И вам нужно написать отдельную функцию для каждой функции вещи, которую вы можете захотеть составить, каждая из которых содержит логику композиции, смешанную с кодом для этой функции.

В этом примере бремя является тривиальным, в зависимости от того, как вы это делаете. Но, как правило, если это так легко сделать маленькие независимые части, которые вы затем склеиваете, чтобы создать свой составной код, то это хороший способ сделать это.

1 голос
/ 25 января 2012

Ваши два примера равносильны одному и тому же, за исключением того, что в одном случае вы используете стиль без очков, а в другом - нет.

Единственное, что вам нужно (и комучитает твой код) найди самый читаемый.В некоторых случаях я считаю стиль без точек наиболее естественным;это один из таких случаев.

...