ue5python原理

Python09

ue5python原理,第1张

Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后解释器一条一条执行字节码指令,从而完成程序的执行。

1.1python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后解释器会从编译得到的PyCodeObject对象中一条一条执行字节码指令,

并在当前的上下文环境中执行这条字节码指令,从而完成程序的执行。Python解释器实际上是在模拟操作中执行文件的过程。PyCodeObject对象

中包含了字节码指令以及程序的所有静态信息,但没有包含程序运行时的动态信息——执行环境(PyFrameObject)

2. 字节码

字节码在python解释器程序里对应的是PyCodeObject对象

.pyc文件是字节码在磁盘上的表现形式

2.1从整体上看:OS中执行程序离不开两个概念:进程和线程。python中模拟了这两个概念,模拟进程和线程的分别是PyInterpreterState和

PyTreadState。即:每个PyThreadState都对应着一个帧栈,python解释器在多个线程上切换。当python解释器开始执行时,它会先进行一

些初始化操作,最后进入PyEval_EvalFramEx函数,它的作用是不断读取编译好的字节码,并一条一条执行,类似CPU执行指令的过程。函数内部

主要是一个switch结构,根据字节码的不同执行不同的代码。

3. .pyc文件

PyCodeObject对象的创建时机是模块加载的时候,及import

Python test.py会对test.py进行编译成字节码并解释执行,但是不会生成test.pyc

如果test.py加载了其他模块,如import urlib2, Python会对urlib2.py进行编译成字节码,生成urlib2.pyc,然后对字节码进行解释

如果想生成test.pyc,我们可以使用Python内置模块py_compile来编译。

加载模块时,如果同时存在.py和pyc,Python会尝试使用.pyc,如果.pyc的编译时间早于.py的修改时间,则重新编译.py并更新.pyc。

4. PyCodeObject

Python代码的编译结果就是PyCodeObject对象

typedef struct {

PyObject_HEAD

int co_argcount/* 位置参数个数 */

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/* 内部嵌套函数引用的变量名集合 */

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

PyObject *co_filename/* 代码所在文件名 */

PyObject *co_name/* 模块名|函数名|类名 */

int co_firstlineno/* 代码块在文件中的起始行号 */

PyObject *co_lnotab/* 字节码指令和行号的对应关系 */

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

} PyCodeObject

5. .pyc文件格式

加载模块时,模块对应的PyCodeObject对象被写入.pyc文件

6.分析字节码

6.1解析PyCodeObject

Python提供了内置函数compile可以编译python代码和查看PyCodeObject对象

6.2指令序列co_code的格式

opcode oparg opcode opcode oparg …

1 byte 2 bytes 1 byte 1 byte 2 bytes

Python内置的dis模块可以解析co_code

7. 执行字节码

Python解释器的原理就是模拟可执行程序再X86机器上的运行,X86的运行时栈帧如下图

Python解释器的原理就是模拟上述行为。当发生函数调用时,创建新的栈帧,对应Python的实现就是PyFrameObject对象。

PyFrameObject对象创建程序运行时的动态信息,即执行环境

7.1 PyFrameObject

typedef struct _frame{

PyObject_VAR_HEAD //"运行时栈"的大小是不确定的

struct _frame *f_back//执行环境链上的前一个frame,很多个PyFrameObject连接起来形成执行环境链表

PyCodeObject *f_code//PyCodeObject 对象,这个frame就是这个PyCodeObject对象的上下文环境

PyObject *f_builtins//builtin名字空间

PyObject *f_globals//global名字空间

PyObject *f_locals//local名字空间

PyObject **f_valuestack//"运行时栈"的栈底位置

PyObject **f_stacktop//"运行时栈"的栈顶位置

//...

int f_lasti//上一条字节码指令在f_code中的偏移位置

int f_lineno//当前字节码对应的源代码行

//...

//动态内存,维护(局部变量+cell对象集合+free对象集合+运行时栈)所需要的空间

PyObject *f_localsplus[1]

} PyFrameObject

每一个 PyFrameObject对象都维护了一个 PyCodeObject对象,这表明每一个 PyFrameObject中的动态内存空间对象都和源代码中的一段Code相对应。

都可以,没有声明其他编码方法,即使用ascii编码作为标准编码方法。

要定义源文件的编码方式,应在文件的第一行或第二行中放置声明,例如:

[python] view plain copy

#coding=<encoding name>

或者(使用流行编辑器中的格式化方式)

[python] view plain copy

#!/usr/bin/python

# -*- coding: <encoding name>-*-

或者

[python] view plain copy

#!/usr/bin/python

# vim: set fileencoding=<encoding name>:

扩展资料:

执行python时,.py文件中的源代码首先编译成python的字节码,然后由python虚拟机执行编译后的字节码。该机制的基本思想与Java、.NET相一致。

但是,与Python虚拟机和Java或.NET虚拟机不同,Python的虚拟机是一种更高级的虚拟机。

这里的高级不是一般意义上的高级。不是Python的虚拟机比Java或.NET更强大,但是Python的虚拟机比Java或.NET更远离真实的机器。

或者这样说,python的虚拟机是一个更高层次的抽象虚拟机。由基于c的python编译的字节码文件,通常采用.pyc格式。

此外,python还可以在交互模式下运行。例如,主流操作系统unix/linux、mac和windows可以直接以命令模式运行python交互环境。互操作性可以通过直接发出操作命令来实现。

参考资料来源:百度百科-Python

python解释器的介绍:

解释器由一个编译器和一个虚拟机构成,编译器负责将源代码转换成字节码文件,而虚拟机负责执行字节码。

所以,解释型语言其实也有编译过程,只不过这个编译过程并不是直接生成目标代码,而是中间代码(字节码),然后再通过虚拟机来逐行解释执行字节码。

计算机的大脑是CPU, 中文名叫中央处理器,它仍然不能直接处理 Python 语言。CPU 只能直接处理机器指令语言,那是一种由0和1数字组成的语言,这是一种我们人很难直接写出来的语言。

所以,我们需要一个翻译,把Python语言翻译成 计算机CPU 能听懂的机器指令语言,这样计算机才能按照 我们的Python程序的要求去做事。.py结尾的文件需要解释器去运行执行。

执行过程原理:

1.执行 python XX.py 后,将会启动 Python 的解释器。

2.python解释器的编译器会将.py源文件编译(解释)成字节码生成PyCodeObject字节码对象存放在内存中。

3.python解释器的虚拟机将执行内存中的字节码对象转化为机器语言,虚拟机与操作系统交互,使机器语言在机器硬件上运行。

4.运行结束后python解释器则将PyCodeObject写回到pyc文件中。当python程序第二次运行时,首先程序会在硬盘中寻找pyc文件,如果找到,则直接载入,否则就重复上面的过程。

Python解释器执行程序的三个阶段:

第一步:先启动python3解释器。

第二步:Python3解释器就像一个文本编辑器一样将文件python3 D:\test.py从硬盘读入内存。

第三步:Python3解释器解释执行文件代码。

只有第三阶段才识别python的语法。