environment
调用一个用户函数:
- create a new frame
- bind 两个实参到形参上
- 执行函数体
nested definitions嵌套定义
- 每个用户函数都有parent frame(often global)
- 函数的parent 就是定义它的frame
- 每个local frame 有一个parent frame(often global)
- the parent of a frame is the paret of the function called
lambda 表达式
1 | square = lambda x : x * x |
Function Currying
给定一个函数 f(x, y),我们可以定义另一个函数 g 使得 g(x)(y) 等价于 f(x, y)。在这里,g 是一个高阶函数,它接受单个参数 x 并返回另一个接受单个参数 y 的函数。这种转换称为柯里化(Curring)。
return statemenst
A return statement completes the evaluation of a call expression and provides its value f(x) for user-defined function f: switch to a new environment; execute f’s body
return statement within f: switch back to the previous environment; f(x) now has a value
closure
闭包(closure) 是一个函数(通常是内部函数),它“记住”了定义时所在的外部作用域中的变量,即使外部函数已经执行完毕。
闭包 = 函数本身 + 它能访问的外部变量环境(enclosing environment)
🍰 举个例子(直观理解)
1 | def outer(): |
执行过程:
调用
outer()
:- 创建局部变量
x = 10
- 定义内部函数
inner()
- 返回
inner
函数对象(不是执行它!)
- 创建局部变量
即使
outer()
执行结束、它的局部变量x
按理说应该被销毁,
但因为inner()
引用了x
,Python 会把x
保存在闭包里。当执行
f()
时,inner
仍然能访问x=10
。
⚙️ 闭包的三个必要条件
要形成闭包,必须满足以下条件:
函数嵌套(函数里定义函数)
1
2def outer():
def inner(): ...内部函数引用了外部函数的变量
1
2x = 10
def inner(): print(x)外部函数返回内部函数
1
return inner
满足这三点,就形成闭包。
🧩 闭包的价值
闭包能让函数“记住”状态,非常适合用于:
1. 数据封装
不用类就能保存数据。
1 | def make_counter(): |
这里 count
永远“活”在 add_one
的闭包中。
2. 延迟计算
1 | def multiplier(n): |
times3
记住了 n=3
,即使外层函数 multiplier
早就结束。
3. 函数工厂(function factory)
闭包经常用于生成一类带记忆的函数,比如:
1 | def power(p): |