手写 Python 虚拟机
海纳
华为资深编译专家,原 Huawei JDK 团队负责人
1186 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已更新 21 讲/共 28 讲
导学|直播加餐:三小时掌握C++ (3讲)
手写 Python 虚拟机
15
15
1.0x
00:00/00:00
登录|注册

17|函数闭包:函数式编程的重要支撑

你好,我是海纳。
我们通过前面那么多节课的努力,先后实现了函数调用、内建方法、函数传参等特性。在虚拟机中,函数机制的实现都离不开 FunctionObject 和 FrameObject 这两个对象。
有了 FunctionObject,一个函数就可以像普通的整数或者字符串那样,作为参数传递给另外一个函数,也可以作为返回值被传出函数。所以,在 Python 语言中,函数也和整数类型、字符串类型一样,是第一类公民(first class citizen)
把函数作为第一类公民,使新的编程范式成为可能,但它也引入了一些必须要解决的问题,例如自由变量和闭包的问题。这节课我们就先来实现它。

函数闭包

在函数中查找变量的时候,遵循 LEBG 规则。其中 L 代表局部变量,E 代表闭包变量(Enclosing),G 代表全局变量,B 则代表虚拟机内建变量。
第 11 课,我们提到了全局变量和局部变量,但当时没有解释闭包变量是什么,这节课我们专门研究闭包变量的功能和影响。我们先来看一个最简单的例子。
def func():
x = 2
def say():
print(x)
return say
f = func()
f()
运行这个例子,最后一行会打印出 2。
首先,调用 func 的时候,得到返回值是在 func 函数内部定义的函数 say。所以变量 f(第 9 行)指向的是函数 say,调用它的时候就会打印 2(第 10 行)。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

1. 闭包是函数式编程的重要支撑,通过闭包变量实现了函数作为第一类公民的特性。 2. 闭包变量在字节码中通过STORE_DEREF和LOAD_CLOSURE指令实现,内部函数引用的外部变量被称为cell变量。 3. MAKE_FUNCTION指令在Python 3.8中采用特殊值0x8来表示创建闭包对象,将外部定义的变量一起打包成闭包。 4. 实现闭包功能需要理解字节码的具体动作,以便能够实现闭包功能。 5. 实现闭包功能需要设计闭包的总体架构,包括在FrameObject中添加_closure变量表、使用LOAD_CLOSURE和STORE_DEREF指令等。 6. 实现闭包功能需要创建CellObject类来实现引用的能力,记录变量表和变量在表中的序号。 7. 实现闭包功能需要在FrameObject中引入closure域,记录所有的cell变量,并按照外到内的顺序排放。 8. 实现闭包功能需要补全MAKE_FUNCTION的功能,当操作数为0x8时,需要向FunctionObject里传递cell变量表。 9. 函数修饰器是一种特殊类型的函数,它接受另一个函数作为输入参数,可以在修饰器内部访问和操作被传入的函数。 10. 函数修饰器功能本质上是由函数及其相关的引用环境组合而成的实体,允许一个函数记住并访问它自身作用域以外的变量。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手写 Python 虚拟机》
新⼈⾸单¥59
立即购买
登录 后留言

精选留言

由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论
显示
设置
留言
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部