高阶函数和帧堆叠

Higher Order Functions and Frame Stacking

我一直在努力理解使用递归调用的给定高阶函数确定框架范围的概念。我可以举一个我在 class 中学到的例子:

def stack(default=lambda x: 0):
    def make(key, code):
        def take(attempt):
            if key == attempt:
                return code
            else:
                return default(attempt)
        return take, stack(take)
    return make 

据我了解,我们正在堆叠我们的 make 函数,在调用 take 时,它​​将评估当前和之前对 make 函数的调用,以查看 attempt 是否与我们的键之一匹配。

更笼统地说,这个 H.O.F 操作背后的概念是什么?我如何从中制作类似的代码?

#doctests 
>>> make = stack()
>>> take1, make1 = make('key1', 'code1')  
>>> take2, make2 = make1('key2', 'code2')
>>> take3, make3 = make2('key3', 'code3') 
>>> take3('key1')
code1 

确实,这样一个涉及多个闭包的双重嵌套内部函数非常复杂,难以理解。查看动态定义的内部函数在特定情况下的实际情况可能会有所帮助。例如,在 运行 您的示例代码之后, take 函数将等效于这样定义:

def take1(attempt):
    if 'key1' == attempt:
        return 'code1'
    else:
        return 0


def take2(attempt):
    if 'key2' == attempt:
        return 'code2'
    else:
        return take1(attempt)


def take3(attempt):
    if 'key3' == attempt:
        return 'code3'
    else:
        return take2(attempt)

看看这段代码,就更容易理解为什么是take3('key3') == 'code3'take3('key1') == 'code1'了。您可以看到函数的 else 分支作为一种默认值级联工作,启用正确的密钥查找,如果找不到密钥,最终会回退到 0

为了熟悉高阶函数的概念,我肯定会建议从一些不太复杂的东西开始,例如制作简单乘法函数的工厂函数:

def make_multiplier(n):

    def fn(x):
        return x * n

    return fn


multiply_by_3 = make_multiplier(3)
multiply_by_5 = make_multiplier(5)
>>> multiply_by_3(2)
6
>>> multiply_by_3(5)
15
>>> multiply_by_5(2)
10
>>> multiply_by_5(5)
25

这两个动态生成的函数将像您手动定义它们一样工作

def multiply_by_3(x):
    return x * 3


def multiply_by_5(x):
    return x * 5