python 字节码操作_Python字节码在CPython中到底如何运行?

如果您想查看某些代码的字节码(源代码,实时函数对象或代码对象等),则2735741803923223244032模块将告诉您所需的确切信息。 例如:

>>> dis.dis('i/3')

1 0 LOAD_NAME 0 (i)

3 LOAD_CONST 0 (3)

6 BINARY_TRUE_DIVIDE

7 RETURN_VALUE

compiler_addop文档说明了每个字节码的含义。 例如compiler_addop:

将与compiler_addop相关的值压入堆栈。

要了解这一点,您必须知道字节码解释器是虚拟堆栈机,什么是compiler_addop。 compiler_addop模块文档具有一个漂亮的表,其中显示了最重要的内部对象的最重要属性,因此您可以看到code是code对象的属性,其中包含局部变量名称的元组。 换句话说,LOAD_NAME 0推送与第0个局部变量相关联的值(并且27357418039232440440很有帮助地查找了该变量,并看到第0个局部变量名为2735741803923244044037)。

足以看到一串字节码还不够。 解释器还需要代码对象的其他属性,在某些情况下还需要函数对象的属性(这也是本地和全局环境的来源)。

compiler_addop模块还具有一些工具,可以帮助您进一步研究实时代码。

这足以找出很多有趣的东西。 例如,您可能知道Python在编译时会根据您是否在函数体内的任何位置(以及任何compiler_addop或code语句)将其分配给函数中的变量来确定是局部变量,闭包变量还是全局变量; 如果编写三个不同的函数并比较它们的反汇编(以及其他相关属性),则可以很容易地弄清楚它必须执行的操作。

(这里棘手的一点是了解闭包单元。要真正做到这一点,您将需要具有3个功能级别,以了解中间的功能如何将最内层的功能向前推进。)

要了解字节码的解释方式以及堆栈机的工作方式(在CPython中),您需要查看2735741803923223244032源代码。 thy435和eyquem的回答已经涵盖了这一点。

了解如何仅读取compiler_addop文件需要更多信息。 Ned Batchelder撰写了一篇很棒的(如果有些过时的话)博客文章,称为.pyc文件的结构,其中涵盖了所有棘手且未充分记录的部分。 (请注意,在3.3中,一些与导入相关的通用代码已从C移到了Python,这使它更容易遵循。)但是基本上,它只是一些头信息和模块的2735741803903923244033对象(由compiler_addop序列化)。

要了解如何将源代码编译为字节码,这是很有趣的部分。

CPython编译器的设计说明了一切工作原理。 (《 Python开发人员指南》的其他一些部分也很有用。)

对于早期的东西-令牌化和解析-您可以使用compiler_addop模块直接跳到进行实际编译的时间。 然后参阅compiler_addop,了解AST如何转换为字节码。

宏可能很难处理,但是一旦您掌握了编译器如何使用堆栈将其分解为块以及如何使用那些compiler_addop和朋友在当前级别发出字节码的想法,这一切就变得很有意义。

首先让大多数人感到惊讶的一件事是功能的工作方式。 函数定义的主体被编译为代码对象。 然后,将函数定义本身编译为代码(在封闭的函数主体,模块等内部),该代码在执行时将根据该代码对象构建函数对象。 (一旦考虑了闭包必须如何工作,很明显为什么会这样工作。闭包的每个实例都是一个具有相同代码对象的独立函数对象。)

现在您已经准备好开始修补CPython以添加您自己的语句,对吗? 嗯,正如“更改CPython的语法”所示,有很多事情要做对了(如果需要创建新的操作码,还有更多的事情要做)。 您可能会发现学习PyPy和CPython并开始对PyPy进行黑客攻击更加容易,只有在知道自己的工作是明智且可行的之后,才回到CPython。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值