ad

《自己动手写 Python 虚拟机》_更理解虚拟机的意义_6.2.2 函数的参数

网友投稿 127 2023-11-07

【摘要】 本书摘自《自己动手写 Python 虚拟机》一书中第6章,第2节,海纳编著。

6.2.2 函数的参数

函数最重要的功能就是接受参数、进行运算和返回计算结果。上一节展示了函 数如何创建栈帧、进行运算并且返回计算结果的。这一节关注如何向一个函数传递 参数。

Python 中传递参数的机制比很多语言都要复杂,所以参数的实现放在最后讲。 与以前的方法相同,先写测试用例,再观察例子所对应的字节码。创建 test_param. py 如代码清单6.15 所示。

《自己动手写 Python 虚拟机》_更理解虚拟机的意义_6.2.2 函数的参数

首先,在这一段反编译字节码里,CALL_FUNCTION 与上一节有所不同。上一 节中的函数调用都没有带参数,所以这个字节码的参数就是0,在这一节的 add 例子 里,函数调用传递了两个参数,所以这个字节码的参数是2。实际上,在 CALL FUNCTION 之前的两个字节码已经把参数送到栈上了,接下来要做的,只是根据 CALL_FUNCTION 的参数将栈上的值取出来,然后再传给函数栈帧就好了。因此, 在 FrameObject 里增加可以接受参数的功能

=func ->_func_code;

=_codes ->_consts;

=_codes ->_names;

_locals =new Map();

_globals =func ->_globals;

_fast_locals =NULL;

10

if(args){

_fast_locals =new ArrayList()

13

for(inti=0;ilength();i++)(

_fast_locals->set(i,args>get(i));

16

17

18

_stack =new ArrayList();

_loop_stack =new ArrayList();

21

22

23

24

25

26

_frame =frame;

}

32

void Interpreter:;run(CodeObject*codes){

_frame =new FrameObject(codes);

while(_frame->has_more_codes()){

unsigned char op_ccde =_frame >get_op_code();

switch(op_code){

39

case ByteCode::CALL_FUNCTION:

if(op_arg>0){

args =new ArrayList(op_arg);

while(op_arg--){

第41~46行,根据 op_arg 去栈里取出参数,然后将所有的参数以 ArrayList 的 形式传递给 build_frame 。 第27和28行,把函数的参数传递到了 FrameObject 中。 为 FrameObject 的构造函数增加了新的参数,用于表示调用函数时所使用的参数。 第11~17行,将传入的参数放到_fast_locals 中去。这样,就把函数的参数传到函数 中去了。

当函数参数被传到_fast_locals 中去以后,接着就是执行函数了。add 方法的前 两条字节码是 LOAD_FAST, 而 LOAD_FAST 与 LOAD_NAME 、LOAD_CONST 一样,都是往栈上加载一个值(本质上是一个对象),区别在于,是从哪里读取值。 LOAD_CONST 是从 consts 里加载,LOAD_NAME 是从局部变量表里加载,而

LOAD_FAST 6.16所示。

添加了这些修改以后,就可以测试了,本节刚开始的 test_param 的例子可以正 常执行了。运行以后,可以输出3。至此,就完成了函数调用的传参功能。

6.2.3 参数默认值

在定义函数的时候,可以为函数的参数指定默认值。代码清单6.17展示了这样 一个例子。

在调用foo 方法时,如果传的参数刚好就是1,则可以不必给出实参的值。如果 不想让形参取此默认值,则可以通过实参另行给出,这种方式可以简化编程。

思考一下如何在虚拟机里实现这个功能。默认值应该是在函数定义的时候就和 函数绑在一起了,因此, 一定是在 MAKE_FUNCTION 处来实现默认值的功能。

在 MAKE_FUNCTION 处创建FunctionObject, 所以默认值的最佳载体显然是 FunctionObject 。 只需要把默认值记录在 FunctionObject 里,在调用的时候再加以 处理即可。

先做第一件事情,在 FunctionObject 里增加一个域,用于记录函数参数的默认 值

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们 18664393530@aliyun.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:《Python+3自动化软件发布系统》Django 2实战_了解Python的更好方法_3.5.3 Salt-API配置
下一篇:《Python学习笔记 从入门到实战》_更了解Python的途径之一_9.3 命名空间
相关文章

 发表评论

暂时没有评论,来抢沙发吧~

×