红魔咖啡馆

头发越掉越多,头发越掉越少

0%

【CS61A】CS61A——Environments

Environments

Environments in Higher-orde function

Environments

Local Names

e.g.

1
2
3
4
5
6
def f(x,y):
    return g(x)
def g(a):
    return a+y

result = f(1,2)

该代码会报错NameError: global name 'y' is not defined

原因很明显:当执行到行4时,系统在g的作用域中找不到y,接着去全局作用域中也找不到y,因而报错

而对于嵌套函数,函数中定义的函数是可以直接使用嵌套外函数的参数的,因为在同一个作用于下

Function Composition

e.g.

1
2
3
4
5
6
7
8
9
10
11
12
def make_adder(n):
    def adder(k):
        return k+n
    return adder
def square(x):
    return x*x
def triple(x):
    return 3*x
def compose1(f,g):
    def h(x):
        return f(g(x))
    return h

compose1函数将两个函数结合起来计算

compose1(triple,square)(5)的结果为225

compose1(square,triple)(5)的结果为75

compose1(square, makek_adder(2))(3)的结果为25

该函数实际上开辟了两个environments用来分别计算两个函数的return值

Composition

如图中蓝色和绿色的两个environments,每个中都包含了三个作用域,分别用来计算square与make_adder(2)的值,其中make_adder还会先进入adder函数的作用域

Self-Reference

e.g.1

1
2
3
4
5
def print_all(x):
    print(x)
    return print_all

print_all(1)(3)(5)

该函数执行后会输出1

即print_all函数可以在函数体内以return值形式返回自身,因此该函数被调用的次数与第五行后面的括号数一致(即被调用几次)

e.g.2

1
2
3
4
5
6
7
def print_sums(x):
    print(x)
    def next_sum(y):
        return print_sums(x+y)
    return next_sum

print_sums(1)(3)(5)

函数会把括号后面的数依次相加,输出每次相加的和

首先传入x=1,打印1,定义next_sum函数,print_sums函数返回该函数,并传入y=3,next_sum返回print_sums函数,传入值为x+y=4

再次打印4,定义next_sum函数,print_sums函数返回该函数,并传入y=5,next_sum返回print_sums函数,传入值为x+y=9

再次打印9,没有参数传入,结束

因此要注意调用表达式中传入的参数去了哪里:

1传入了print_sums,而3和5传入了print_sums的返回值next_sum函数用于求和

Currying

注意以下两种函数

1
2
3
4
5
def make_adder(n):
    return lambda k:n+k

def add(x,y):
    return x+y

make_adder函数一次调用一个参数,返回一个函数再调用参数

add函数调用多个参数,返回最终结果

我们可以用以下函数将add函数转换为make_adder函数

1
2
3
4
5
6
def curry(f):
    def g(x):
        def h(y):
            return f(x,y)
        return h
    return g

这样,当我们把add函数传入curry函数,我们就可以通过一次调用一个参数的方法实现相同效果

add_three = curry(add)

add_three(3)(2) >>> 5

定义:柯里化(Currying)是一种处理多元函数的方法。它产生一系列连锁函数,其中每个函数固定部分参数,并返回一个新函数,用于传回其它剩余参数的功能。

即它可以把一个多元函数转换为一系列函数,每个函数传入一个参数,即将f(a,b,c)转换为f(a)(b)(c)