python frame用法_tkinter frame详解「建议收藏」

python frame用法_tkinter frame详解「建议收藏」此文诠释基本的Python虚拟机结构,以及主要的栈操作和帧调用

此文诠释基本的 Python 虚拟机结构,以及主要的栈操作和帧调用。

并使用 Go 语言进行代码逻辑复验。

基于栈的虚拟机(Virtual Machine)

Python 是一门解释型语言,也是一门编译型语言,通过编译器把语法树分析成独有的字节码,从而再链接虚拟机执行字节码,而虚拟机整体架构和运行机制仅仅使用栈结构,非常简单理解的数据结构,但是怎么根据栈,字节码,实现变量、函数调用、类调用,是一个非常难以解释的问题。

栈可以理解成一个集合或一个列表,结构如下:Stack

FIFO:First in, First out(先进后出原则)

FILO:First in, Then out(先进先出原则)

其两种栈结构的区别在于:

// FIFOfor (int i = list.length; i > 0; i –) {} // 3 9 2 5// FILOfor (int i = 0; i < list.length; i ++) {} // 5 2 9 3

化简编译流程Process

首先源代码通过编译器(此处省略数个步骤)分析成帧对象,而帧对象内又包括代码对象。

主要结构是代码对象,代码对象内包含字节码列表,常量列表,变量列表,偏移量列表。

字节码偏移量

每个字节码只占用 1 byte,不包括后带的参数,如果有参数,其也占用 1 byte。名称参数作用

CONST1载入常量

LOAD1加载变量

STORE1赋给变量

ADD-执行加法

SUB-执行减法

MUL-执行乘法

DIV-执行除法

PUT-输出栈顶

POP-弹出栈顶

RET-返回栈顶

CALL形参数量执行函数

注:此字节码列表仅用于代码复验。

可以看出,一个 __code__对象内包含 .co_varnames 和 .co_consts,变量名和常量列表。

而偏移量列表则在字节码列表中,跟随在字节码后,我们用 Go 语言实现,则单独设定个偏移量列表。

虚拟机包含帧调用列表Frame Structure

虚拟机初始化第一个帧为全局帧,全局帧里包含标准方法(BUILTIN),例如

# 整型数据

# len 函数

全局声明的变量、函数、类、等,也包含在全局帧里,而后面加入的帧可以理解成块调用语句,新开的一个作用域,块与块之间的数据不一致。Frames 也是采用栈结构,栈顶是当前执行的帧。

虚拟机仅仅执行帧对象。

帧结构Structure

CODE:代码对象

DATA:计算栈

BLOCK:块栈

LOCAL:变量符号表

BUILTIN:内建符号表

块栈标识当前的循环执行、嵌套循环和异常退出,如果当前是 continue,那么块栈顶是loop,标识循环内的迭代器就应该保存在数据栈中,下次循环依旧是上次的迭代。

代码对象结构Structure

BYTECODE:字节码

CONSTANT:常量

VARIABLE:变量名

OFFSET:偏移量

偏移量标识了有参数的字节码的对象位置,例如 CONST 4,加载常量列表里第 5 个数据。

STORE 2,把栈顶的值赋给变量名列表里第 3 个变量名。

函数调用实例

两个帧实现函数参数传递和返回值传递。

// foo

BYTECODE: [

CONST, // 5

LOAD, // x

LOAD, // y

ADD, // x + y

MUL, // * 5

PUT, // 输出

RET // 返回

],

CONSTANT: [ None, 5 ],

VARAIBLE: [ ‘x’, ‘y’ ]

OFFSET: [

1, // 5

0 // x

1, // y

]

// main

BYTECODE: [

CONST, // 3

CONST, // 6

CONST, // foo

CALL, // 2

PUT, // 45

POP, // 销毁栈顶

RET // 执行完毕

],

CONSTANT: [ None, 3, 6, foo ],

VARAIBLE: [ ]

OFFSET: [

1, // 3

2 // 6

3, // foo

2, // CALL

]

函数参数传递首先 const 把函数加载出来(此处和 cpython 不同)

根据函数形参数量,pop 数据栈,得到参数,对比类型和其他错误。

把参数赋给函数代码对象里的 local variables,即符号表,此处完成函数体参数赋值。

函数代码对象如果有参数,位置始终从 var 栈 0 起始,函数体内再声明的变量依次排队。

函数返回值当虚拟机执行到 RET 字节码,把当前栈顶的值赋给当前帧的返回值对象。

函数执行(帧执行)完后,判断当前帧的返回值对象。

如果存在,则推入计算栈,得到返回值。

如 Python 在每个常量列表第一个值始终是 None,即无返回值,则返回 CONST 0 对应 None.

Python 中其他对象Process

To be continue…

Go 语言实现:bingxio/go-pyframe​github.com4528e463bf5a26544fed01091c481e49.png

如有帮助,请给个星!!

参考

今天的文章python frame用法_tkinter frame详解「建议收藏」分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/64270.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注