python源码编译后得到的是_《python源代码剖析》笔记 Python的编译结果

1.python的运行过程

1)对python源码进行编译。产生字节码

2)将编译结果交给python虚拟机。由虚拟机依照顺序一条一条地运行字节码,产生运行结果

SouthEast

2.Python编译器的编译结果——PyCodeObject对象

Python编译器的编译结果中包括了字符串、常量值、字节码等在源码中出现的一切实用的静态信息。

在Python执行期间,这些静态信息被PyCodeObject对象中

在Python执行结束后。这些信息会被存储在pyc文件里

PyCodeObject对象和pyc文件是Python对源文件编译结果的两种不同存在形式

3.Python源代码中的PyCodeObject

/* Bytecode object */

typedef struct {

PyObject_HEAD

int co_argcount;/* 位置參数个数*/

int co_nlocals;/* 局部变量个数,包含位置參数个数*/

int co_stacksize;/* 须要的栈空间 */

int co_flags;/* CO_..., see below */

PyObject *co_code;/* 字节码指令序列,以PyStringObject形式存在 */

PyObject *co_consts;/* PyTupleObject对象,保存全部的常量 */

PyObject *co_names;/* PyTupleObject对象。保存全部符号 */

PyObject *co_varnames;/* 局部变量名集合 */

PyObject *co_freevars;/* 实现闭包须要用到的东西 */

PyObject *co_cellvars; /* 内部嵌套函数所引用的局部变量名集合 */

/* The rest doesn't count for hash/cmp */

PyObject *co_filename;/* Code Block所相应的.py文件的完整路径 */

PyObject *co_name;/* Code Block的名字,一般是函数名或类名 */

int co_firstlineno;/* Code Block所相应的.py文件的起始行 */

PyObject *co_lnotab;/* 字节码指令与.py文件里source code行号的相应关系。以PyStringObject的等式存在 */

void *co_zombieframe; /* for optimization only (see frameobject.c) */

PyObject *co_weakreflist; /* to support weakrefs to code objects */

} PyCodeObject;

Code Block:当进入一个新的名字空间,或者说作用域的时候,就算是进入了一个新的Code Block:当进入一个新的名字空间。或者说作用域的时候,就算是进入了一个新的

Code Block。一个 Code Block相应一个 PyCodeObject

名字空间是符号的上下文环境。名字空间链是多个名字空间嵌套在一起。

在Python中,module、类、函数都相应着一个独立的名字空间

#会产生三个 PyCodeObject。分别相应整个文件。class A和 def Fun

class A:

pass

def Fun():

pass

a = A()

Fun()

3.pyc文件

pyc文件里包括了三部分独立的信息:

Python的magic number --> 保证Python的兼容性

pyc文件的创建时间 --> 能够使Python自己主动将pyc文件与最新的py文件进行同步

PyCodeObject对象

将内存中的PyCodeObject对象写入到pyc文件,须要下面几个函数

w_byte

w_long

w_string

PyMarshal_WriteObjectToFile会调用w_object,w_object会遍历 PyCodeObject中的全部域,

将这些域依次写入。

写入终于归结为两种形式:对数值的写入和对字符串的写入static void w_object(PyObject *v, WFILE *p)

{

//……

else if (PyCode_Check(v))

{

PyCodeObject *co = (PyCodeObject *)v;

w_byte(TYPE_CODE, p);

w_long(co->co_argcount, p);

w_long(co->co_nlocals, p);

w_long(co->co_stacksize, p);

w_long(co->co_flags, p);

w_object(co->co_code, p);

w_object(co->co_consts, p);

w_object(co->co_names, p);

w_object(co->co_varnames, p);

w_object(co->co_freevars, p);

w_object(co->co_cellvars, p);

w_object(co->co_filename, p);

w_object(co->co_name, p);

w_long(co->co_firstlineno, p);

w_object(co->co_lnotab, p);

}

//……

}

w_object在写入对象之前会先写入TYPE_LIST、TYPE_CODE或者TYPE_INT标识,它们对

pyc文件的再次载入具有至关关键的数据。Python在pyc文件里发现这种标识,则预示着

一个对象的结束,新对象的開始。并且也知道了对象的类型。

4.向pyc文件里写入字符串

写入过程中的结构体WFILEtypedef struct {

FILE *fp;

PyObject *strings; //在写入时指向dict,在读出时指向list

} WFILE;

WFILE中的strings在marshal的时候指向一个PyDictObject对象(PyStringObject,PyIntObject)

//w_object对于字符串的处理

else if (PyString_CheckExact(v)) {

if (p->strings && PyString_CHECK_INTERNED(v)) {

//[1]:获得 PyStringObject对象在strings中的序号

PyObject *o = PyDict_GetItem(p->strings, v);

//[2]:intern字符串的非首次写入

if (o) {

long w = PyInt_AsLong(o);

w_byte(TYPE_STRINGREF, p);

w_long(w, p);

goto exit;

}

//[3]:intern字符串的首次写入

else {

int ok;

o = PyInt_FromSsize_t(PyDict_Size(p->strings));

ok = o &&

PyDict_SetItem(p->strings, v, o) >= 0;

Py_XDECREF(o);

if (!ok) {

p->depth--;

p->error = WFERR_UNMARSHALLABLE;

return;

}

w_byte(TYPE_INTERNED, p);

}

}

//[4]:写入普通字符串

else {

w_byte(TYPE_STRING, p);

}

//写入字符串

w_pstring(PyBytes_AS_STRING(v), PyString_GET_SIZE(v), p);

}

//...

怎么确定一个字符串要不要intern?

写入pyc文件时,strings是dict类型

SouthEast

从pyc文件里读取的时候,strings是list类型

SouthEast

5.一个PyCodeObject,多个PyCodeObject

PyCodeObject中的co_consts是嵌套的PyCodeObject的藏身之处

SouthEast

6.Python的字节码

104条字节码

STOP_CODE()

Indicates end-of-code to the compiler, not used by the interpreter.

NOP()

Do nothing code. Used as a placeholder by the bytecode optimizer.

POP_TOP()

Removes the top-of-stack (TOS) item.

ROT_TWO()

Swaps the two top-most stack items.

ROT_THREE()

Lifts second and third stack item one position up, moves top down to position three.

ROT_FOUR()

Lifts second, third and forth stack item one position up, moves top down to position four.

//...

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值