Во вложенных функциях, как заставить текущую функцию придерживаться только возвращенных значений предыдущей функции? - PullRequest
0 голосов
/ 30 июня 2019

Это алгоритмический вопрос.Я хочу иметь функцию более высокого порядка, которая может многократно получать аргументы, например func(3, 5)(4, 9)(1, 2)(...).Я знаю, что все, что мне нужно, это определить функцию, которая возвращает функцию (внутреннюю функцию), возможно, вот так (хотя я не уверен, что это правильные коды)

def func(a, b = 0):
    def inner_func(c, d):
        nonlocal b
        b += c + d
        print(b)
        ...
        return inner_func
    return inner_func(a, b)

Поэтому, когда мы запускаем:

test0 = func(1, 2)
test1 = test0(2, 3)

мы должны получить выходные данные как минимум:

5
10

Но если мы запустим:

test0 = func(1, 2)
test1 = test0(2, 3)
test_add = test0(2, 3)

, то результат будет:

5
10
15

Однако я хочу, чтобы test_add = test0(2, 3) возвращал точно то же, что возвращает test1 = test0(2, 3), то есть 10.

Expected outputs:
5
10
10

Я должен найти способ заставить текущую функцию test0(2, 3) придерживатьсятолько для входов предыдущей функции func(1, 2), которые 1 и 2.Больше примеров:

test0 = func(1, 2)
test1 = test0(2, 3)

Expected outputs:
5
10

test_add = test0(3, 5)

Expected outputs: 13 
But got: 18

Итак, как мне изменить код для этой цели?

1 Ответ

1 голос
/ 30 июня 2019

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

В этой точке использование функции в качестве типа результата является неправильным выбором.Комбинация функциональности и внутреннего состояния - это то, для чего предназначены классы .

Просто напишите быстрый вспомогательный класс, который хранит состояние:

class func_result:
    def __init__(self, prev):
        self.prev = prev
    def __call__(self, a, b):
        val = a+b+self.prev
        print(val)
        return func_result(val)

def func(a, b):
    return func_result(b)(a,b)

test0 = func(1, 2)
test1 = test0(2, 3)
test_add1 = test1(2, 3)
test_add2 = test0(2, 3)
test_add3 = test0(3, 5)
5
10
15
10
13

Если вам не нравится тот факт, что класс func_result теперь доступен, вы можете вложить его в функцию:

def func(a, b):
    class func_result:
        def __init__(self, prev):
            self.prev = prev
        def __call__(self, a, b):
            val = a+b+self.prev
            print(val)
            return func_result(val)
    return func_result(b)(a,b)
...