热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

pythoncode_python笔记_codeobject

一、背景python先把代码(也就是.py文件)编译成字节码(对应codeobject对象),然后将字节码提交给python虚拟机,虚拟机按照顺序执行字

一、背景

python先把代码(也就是.py文件)编译成字节码(对应codeobject对象),然后将字节码提交给python虚拟机,虚拟机按照顺序执行字节码指令完成了程序的执行。本文关注的对象就是codeobject对象。在磁盘上codeobject对象的表现形式就是.pyc文件。

二、编译成字节码

python中有一个内置函数compile(),可以将源文件编译成codeobject,首先看这个函数的说明:

compile(...)

compile(source, filename, mode[, flags[, dont_inherit]]) -> code object

参数1:源文件的内容字符串

参数2:源文件名称

参数3:exec-编译module,single-编译一个声明,eval-编译一个表达式

一般使用前三个参数就够了

使用示例:

#src_file.py

#some function

def f(d=0):

c=1

print "hello"

a=9

b=8

f()

#命令行模式中打开源文件进行编译

>>a=open('src_file.py','r').read()

>>co=compile(a,'src_file','exec')

>>type(co)

#编译出了codeobject对象

>>

三、codeobject对象的属性

codeobject有哪些变量,接上节的内容分析一下

#所有的符号名称

>>> print co.co_names

('f', 'a', 'b')

#模块名、函数名、类名

>>>print co.co_name

#常量集合、函数f和两个int常量a,b,d

>>print co.co_consts

(0, , 9, 8, None)

#可以看到f函数也是一个codeobject,打印f中的局部变量

>>print co.co_consts[1].co_varnames

('c',)

#字节码指令

>>print co.co_code

dZdZdZedS

#代码块在文件中的起始行号

>>print co.co_consts[1].co_firstlineno

2

#代码栈大小

>>print co.co_stacksize

2

#文件名

>>> print co.co_filename

src_file

codeobject的co_code代表了字节码,这个字节码有什么含义?我们可以使用dis模块进行python的反编译:

import dis

dis.dis(co)

>>output

2 0 LOAD_CONST 0 (0)

3 LOAD_CONST 1 ()

6 MAKE_FUNCTION 1

9 STORE_NAME 0 (f)

5 12 LOAD_CONST 2 (9)

15 STORE_NAME 1 (a)

6 18 LOAD_CONST 3 (8)

21 STORE_NAME 2 (b)

7 24 LOAD_NAME 0 (f)

27 CALL_FUNCTION 0

30 POP_TOP

31 LOAD_CONST 4 (None)

34 RETURN_VALUE

从反编译的结果来看,python字节码其实是模仿的x86的汇编,将代码编译成一条一条的指令交给一个虚拟的cpu去执行。

第一列:行号

第二列:指令在代码块中的偏移量

第三列:指令

第四列:操作数

第五列:操作数说明

具体在执行字节码的时候,python需要创建栈,又是一个比较重要的对象PyFrameObject。以后再研究。



推荐阅读
author-avatar
200355人
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有