python边用边总结(二)python的执行

https://baike.baidu.com/item/Python/407313?fr=aladdin

https://www.jianshu.com/p/f540e540f940 这里介绍了opcod.h

python在执行时,首先会将.py文件中的源代码编译成Python的byte code(字节码),然后用python virtual machine来执行这些编译好的byte code。这种机制跟Java,.Net是一致的,但是python的虚拟机抽象层次更高

  • byte code

字节码是一种包含执行程序,由一序列op代码/数据对组成的二进制文件,是一种中间码,它比机器码更抽象

  • opcode

opcode(operating code)就是机内码、操作码,也就是指令序列号,用来告诉CPU需要执行哪一条指令

  • 指令码

指令码(Instruction Code) /机器码(Machine Code),计算机指令代码,机器语言,用来表示指令集中的指令的代码

  • dis

https://www.jianshu.com/p/f45e443cdfd7 解释了opcode与优化

dis是python提供的对操作码进行分析的内置模块

def func():
    a = 10
    b = 20
    c = a + b
    return c
dis.dis(func)

###输出结果
2           0 LOAD_CONST               1 (10)
              3 STORE_FAST               0 (a)

  3           6 LOAD_CONST               2 (20)
              9 STORE_FAST               1 (b)

  4          12 LOAD_FAST                0 (a)
             15 LOAD_FAST                1 (b)
             18 BINARY_ADD
             19 STORE_FAST               2 (c)

  5          22 LOAD_FAST                2 (c)
             25 RETURN_VALUE

###

 这里面的LOAD_CONST STORE_FAST以及BINARY_ADD即是我们opcode,python基于栈语言,这里LOAD_CONST即为压栈操作,而STORE_FAST是将栈顶元素赋给参数指定的变量。

python代码在编译完成后再内存种的对象称为PyCodeObject,用c定义

typedef struct {
    PyObject_HEAD
    int co_argcount;             /* #arguments, except *args */
    int co_kwonlyargcount;       /* #keyword only arguments */
    int co_nlocals;              /* #local variables */
    int co_stacksize;            /* #entries needed for evaluation stack */
    int co_flags;                /* CO_..., see below */
    PyObject *co_code;           /* instruction opcodes */
    PyObject *co_consts;         /* list (constants used) */
    PyObject *co_names;          /* list of strings (names used) */
    PyObject *co_varnames;       /* tuple of strings (local variable names) */
    PyObject *co_freevars;       /* tuple of strings (free variable names) */
    PyObject *co_cellvars;       /* tuple of strings (cell variable names) */
    /* The rest doesn't count for hash or comparisons */
    unsigned char *co_cell2arg;  /* Maps cell vars which are arguments. */
    PyObject *co_filename;       /* unicode (where it was loaded from) */
    PyObject *co_name;           /* unicode (name, for reference) */
    int co_firstlineno;          /* first source line number */
    PyObject *co_lnotab;         /* string (encoding addr<->lineno mapping) See
                                    Objects/lnotab_notes.txt for details. */
    void *co_zombieframe;        /* for optimization only (see frameobject.c) */
    PyObject *co_weakreflist;    /* to support weakrefs to code objects */
} PyCodeObject;

这里的co_consts和co_names分别存放了所有的常量和所有的变量。

LOAD_CONST 0 表示将co_consts中的第0个(下标0)放入栈中。
STORE_FAST 0 表示将栈顶元素赋值给co_names中存放的第0个元素。

co_code中存储了操作码序列,编译好的操作码以二进制的方式进行存储,co_code = [(opcode}[args{0,1}]+的形式,其中opcode占用一个byte,编号90以下的操作码不需要参数,90及以上的操作码需要两个byte的args,下面是func函数编译之后得到的PyCodeObject信息

https://github.com/yukunxie/PythonCodeObjectParser/blob/master/codeparser.py这里提供了pythonObject的查看工具

<item idx="0" name="func" type="codeobject">
            <co_consts count="3">
                <item idx="0">None</item>
                <item idx="1">10</item>
                <item idx="2">20</item>
            </co_consts>
            <co_names count="0"/>
            <co_varnames count="3">
                <name idx="0">a</name>
                <name idx="1">b</name>
                <name idx="2">c</name>
            </co_varnames>
            <co_cellvars count="0"/>
            <co_freevars count="0"/>
            <co_filename>code.py</co_filename>
            <co_ename>func</co_ename>
            <co_nlocals>3</co_nlocals>
            <co_stacksize>2</co_stacksize>
            <co_argcount>0</co_argcount>
            <co_code>6401007d00006402007d01007c00007c0100177d02007c020053</co_code>
        </item>

python是基于栈操作的,所以频繁的出栈和压栈的操作,效率较低

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值