Environments
Environments in Higher-orde function
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 hcompose1函数将两个函数结合起来计算
compose1(triple,square)(5)的结果为225
compose1(square,triple)(5)的结果为75
compose1(square, makek_adder(2))(3)的结果为25
该函数实际上开辟了两个environments用来分别计算两个函数的return值
如图中蓝色和绿色的两个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+ymake_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)