Higher-Order Function

高阶函数

  • 接受其他函数作为参数的函数

  • 或者将函数作为返回值的函数

作为参数的函数

  • 作为一般方法的函数

    • 更强大的抽象类型:

      • 一些函数表达了计算的一般方法,独立于它们调用的特定函数。

      • 命名和函数允许我们抽象而远离大量的复杂性

      • 每个通用的概念或方程都能映射为自己的小型函数

    • 缺陷

      • 全局帧会被小型函数弄乱

        • 解决方法: 嵌套函数

作为返回值的函数

def make_adder(n):  # 用来定义这个 function
    """
    >>> add_three = make_adder(3)
    >>> add_three(4)
    7
    """
    def adder(k):  # 将要返回的 function , parent 不是 global [parent = f1] 
        return k+n

    return adder  # 返回的是 function

make_adder(4)(3) # 7
returnFunctionExpressionTree
environmentDiagramFroNestedDefStatements
  • 注意 parent 的指向

  • n 在 f2 找没找到,在 f1 找找到了

  • f1 一直存在

Lambda 表达式

  • 使用 Lambda 表达式凭空创建函数,它会求值为匿名函数

  • 函数体具有单个返回表达式的函数

square = lambda x: x * x # lambda x: x * x 求出了一个 function
square(4) # 16
(lambda x: x * x)(3) # 9


>>> def compose1(f,g):
        return lambda x: f(g(x))

#      lambda            x            :          f(g(x))
# "A function that    takes x    and returns     f(g(x))"

# Lambda expressions can be used as an operator
# or operand
negate = lambda f, x: -f(x)
negate(lambda x: x * x, 3)  # -9
  • lambda 表达式做什么?

  • 我们可以把所有的函数写成lambda表达式吗?

  • 在什么情况下 lambda 表达式是有用的?

    • lambda 表达式创建函数。

    • 当对一个 lambda 表达式求值时,它会生成一个函数。

    • 对于那些我们不需要用很久的函数,我们经常使用 lambda 来创建简短的匿名函数。

Iteration

  • function 可以自己调用自己

def print_all(x):
    print(x)
    return print_all

print_all(1)(3)(5)   # 1 3 5

def print_sum(x):
    print(x)
    def sum(y):
        return print_sum(x+y)
    return sum

print_sum(1)(3)(5)   # 1 4 9

if

ifStatements

为什么 if 不是右边的结构?

  • 因为调用的求值规则

逻辑操作

  • 短路

    • A or B

      • A 真 返回 A

        • 1 or 2 # 1

      • A 假 返回 B

        • 0 or 2 # 2

    • A and B

      • A 真 返回 B

        • 1 and 2 # 2

      • A 假 返回 A

        • 0 and 2 # 0

  • 条件语句

    • <consequent> if <predicate> else <alternative>

Design && Function Examples

  • 抽象

    • 函数不区分内部函数和用户自定义函数

  • 变量命名的原则

函数装饰器

  • 将高阶函数用作执行def语句的一部分,叫做装饰器

def trace1(fn):   # 接受函数 f
    def wrapped(x):
        print('-> ', fn, '(', x, ')')    # 打印地址
        return fn(x)  # 返回 f(x)
    return wrapped    # 返回 f(x)

def triple(x):
    return 3 * x

triple # tripe 方法 <function triple at 0x000001458C2EEB80/>

trace1(triple)(4)
# ->  <function triple at 0x000001458C2EEB80> ( 4 )
# 12

@trace1   # 装饰器
def another_triple(x):
    return 3 * x

another_triple # trace1 中的返回函数的方法 <function trace1.<locals>.wrapped at 0x000001458C2EED30>


another_triple(4)
# ->  <function another_triple at 0x000001458C2EEA60> ( 4 )
# 12
  • @trace1 影响 def 的执行规则

    • triple 并没有绑定到这个函数上

    • 而是绑定到了在新定义的函数 triple 上调用 trace1 的返回函数值上。

等价关系:

@trace1   # 装饰器
def another_triple(x):
    return 3 * x

# ==>

def another_triple(x):
    return 3 * x
another_triple = trace1(another_triple)

Last updated

Was this helpful?