文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python虚拟机中的Code obejct有什么作用

2023-07-05 20:27

关注

这篇文章主要介绍了Python虚拟机中的Code obejct有什么作用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python虚拟机中的Code obejct有什么作用文章都会有所收获,下面我们一起来看看吧。

Code Object 数据结构

typedef struct {    PyObject_HEAD    int co_argcount;    int co_kwonlyargcount;    int co_nlocals;    int co_stacksize;    int co_flags;    PyObject *co_code;    PyObject *co_consts;    PyObject *co_names;    PyObject *co_varnames;    PyObject *co_freevars;    PyObject *co_cellvars;              unsigned char *co_cell2arg;     PyObject *co_filename;    PyObject *co_name;    int co_firstlineno;    PyObject *co_lnotab;    void *co_zombieframe;         PyObject *co_weakreflist;   } PyCodeObject;

下面是 code object 当中各个字段的作用:

CodeObject 详细分析

现在我们使用一些实际的例子来分析具体的 code object 。

import disimport binasciiimport typesd = 10def test_co01(c):    a = 1    b = 2    return a + b + c + d

在前面的文章当中我们提到过一个函数是包括一个 code object 对象,test_co01 的 code object 对象的输出结果(完整代码见co01)如下所示:

code   argcount 1   nlocals 3   stacksize 2   flags 0043 0x43   code b'6401007d01006402007d02007c01007c0200177c0000177400001753'  9           0 LOAD_CONST               1 (1)              3 STORE_FAST               1 (a) 10           6 LOAD_CONST               2 (2)              9 STORE_FAST               2 (b) 11          12 LOAD_FAST                1 (a)             15 LOAD_FAST                2 (b)             18 BINARY_ADD             19 LOAD_FAST                0 (c)             22 BINARY_ADD             23 LOAD_GLOBAL              0 (d)             26 BINARY_ADD             27 RETURN_VALUE   consts      None      1      2   names ('d',)   varnames ('c', 'a', 'b')   freevars ()   cellvars ()   filename '/tmp/pycharm_project_396/co01.py'   name 'test_co01'   firstlineno 8   lnotab b'000106010601'

Flags 字段详细分析

我们具体使用 python3.5 的源代码进行分析,在 cpython 虚拟机的具体实现如下所示(Include/code.h):

#define CO_OPTIMIZED0x0001#define CO_NEWLOCALS0x0002#define CO_VARARGS0x0004#define CO_VARKEYWORDS0x0008#define CO_NESTED       0x0010#define CO_GENERATOR    0x0020#define CO_NOFREE       0x0040#define CO_COROUTINE            0x0080#define CO_ITERABLE_COROUTINE   0x0100

如果 flags 字段和上面的各个宏定义进行 & 运算,如果得到的结果大于 0,则说明符合对应的条件。

上面的宏定义的含义如下所示:

现在再分析一下前面的函数 test_co01 的 flags,他对应的值等于 0x43,则说明这个函数满足三个特性分别是 CO_NEWLOCALS,CO_OPTIMIZED 和 CO_NOFREE。

freevars & cellvars

我们使用下面的函数来对这两个字段进行分析:

def test_co02():    a = 1    b = 2    def g():        return a + b    return a + b + g()

上面的函数的信息如下所示(完整代码见co02):

code   argcount 0   nlocals 1   stacksize 3   flags 0003 0x3   code      b'640100890000640200890100870000870100660200640300640400860000'      b'7d0000880000880100177c00008300001753' 15           0 LOAD_CONST               1 (1)              3 STORE_DEREF              0 (a) 16           6 LOAD_CONST               2 (2)              9 STORE_DEREF              1 (b) 18          12 LOAD_CLOSURE             0 (a)             15 LOAD_CLOSURE             1 (b)             18 BUILD_TUPLE              2             21 LOAD_CONST               3 (<code object g at 0x7f133ff496f0, file "/tmp/pycharm_project_396/co01.py", line 18>)             24 LOAD_CONST               4 ('test_co02.<locals>.g')             27 MAKE_CLOSURE             0             30 STORE_FAST               0 (g) 20          33 LOAD_DEREF               0 (a)             36 LOAD_DEREF               1 (b)             39 BINARY_ADD             40 LOAD_FAST                0 (g)             43 CALL_FUNCTION            0 (0 positional, 0 keyword pair)             46 BINARY_ADD             47 RETURN_VALUE   consts      None      1      2      code         argcount 0         nlocals 0         stacksize 2         flags 0013 0x13         code b'8800008801001753' 19           0 LOAD_DEREF               0 (a)              3 LOAD_DEREF               1 (b)              6 BINARY_ADD              7 RETURN_VALUE         consts            None         names ()         varnames ()         freevars ('a', 'b')         cellvars ()         filename '/tmp/pycharm_project_396/co01.py'         name 'g'         firstlineno 18         lnotab b'0001'      'test_co02.<locals>.g'   names ()   varnames ('g',)   freevars ()   cellvars ('a', 'b')   filename '/tmp/pycharm_project_396/co01.py'   name 'test_co02'   firstlineno 14   lnotab b'0001060106021502'

从上面的输出我们可以看到的是,函数 test_co02 的 cellvars 为 ('a', 'b'),函数 g 的 freevars 为 ('a', 'b'),cellvars 表示在其他函数当中会使用本地定义的变量,freevars 表示本地会使用其他函数定义的变量。

再来分析一下函数 test_co02 的 flags,他的 flags 等于 0x3 因为有闭包的存在因此 flags 不会存在 CO_NOFREE,也就是少了值 0x0040 。

stacksize

这个字段存储的是在函数在被虚拟机执行的时候所需要的最大的栈空间的大小,这也是一种优化手段,因为在知道所需要的最大的栈空间,所以可以在函数执行的时候直接分配指定大小的空间不需要在函数执行的时候再去重新扩容。

def test_stack():    a = 1    b = 2    return a + b

上面的代码相关字节码等信息如下所示:

code   argcount 0   nlocals 2   stacksize 2   flags 0043 0x43   code b'6401007d00006402007d01007c00007c01001753'   #  字节码指令 # 字节码指令参数 # 参数对应的值 24           0 LOAD_CONST               1 (1)              3 STORE_FAST               0 (a) 25           6 LOAD_CONST               2 (2)              9 STORE_FAST               1 (b) 26          12 LOAD_FAST                0 (a)             15 LOAD_FAST                1 (b)             18 BINARY_ADD             19 RETURN_VALUE   consts      None # 下标等于 0 的常量      1  # 下标等于 1 的常量      2 # 下标等于 2 的常量   names ()   varnames ('a', 'b')   freevars ()   cellvars ()

我们现在来模拟一下执行过程,在模拟之前我们首先来了解一下上面几条字节码的作用:

LOAD_CONST,将常量表当中的下标等于 i 个对象加载到栈当中,对应上面的代码 LOAD_CONST 的参数 i = 1。因此加载测常量等于 1 。因此现在栈空间如下所示:

Python虚拟机中的Code obejct有什么作用

STORE_FAST,将栈顶元素弹出并且保存到 co_varnames 对应的下标当中,根据上面的字节码参数等于 0 ,因此将 1 保存到 co_varnames[0] 对应的对象当中。

Python虚拟机中的Code obejct有什么作用

LOAD_CONST,将下标等于 2 的常量加载进入栈中。

Python虚拟机中的Code obejct有什么作用

STORE_FAST,将栈顶元素弹出,并且保存到 varnames 下标为 1 的对象。

Python虚拟机中的Code obejct有什么作用

LOAD_FAST,是取出 co_varnames 对应下标的数据,并且将其压入栈中。我们直接连续执行两个 LOAD_FAST 之后栈空间的布局如下:

Python虚拟机中的Code obejct有什么作用

BINARY_ADD,这个字节码指令是将栈空间的两个栈顶元素弹出,然后将两个数据进行相加操作,然后将相加得到的结果重新压入栈中。

Python虚拟机中的Code obejct有什么作用

RETURN_VALUE,将栈顶元素弹出并且作为返回值返回。

从上面的整个执行过程来看整个栈空间使用的最大的空间长度为 2 ,因此 stacksize = 2 。

关于“Python虚拟机中的Code obejct有什么作用”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Python虚拟机中的Code obejct有什么作用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯