您现在所在位置: 首页 > 睿道新闻

怎样在操作中访问python字节码?

发布时间:2020-09-15点击数:


  如果要玩这个,Python标准库中的dis模块很有用;Dis模块为Python字节码提供了一个“反汇编器”,可以轻松获取人类可读的版本,找到各种字节码指令。dis模块的文档涵盖了相关内容,并提供了字节码指令、其功能和参数的完整列表。


  函数dis.dis()反汇编函数、方法、类、模块、编译后的Python代码对象或包含源代码的字符串,并打印可读版本。dis模块中另一个方便的功能是distb()。您可以将其传递给Pythontraceback对象,或者在引发异常后调用它。它将反编译调用堆栈中的顶层函数,打印它的字节码,并插入一个指向在指令中引发异常的指令的指针。


  代码对象可以通过函数的__code__属性来访问,并且包含一些其他重要属性:


  Co_consts是包含出现在函数体中的任何文字常量的元组。


  Co_varnames是一个元组,包含函数体中使用的任何局部变量的名称。


  Co_names是一个元组,包含函数体中引用的任何非局部变量的名称。


  许多字节码指令——尤其是那些涉及推入堆栈以加载内容或将内容存储在变量和属性中的指令——将使用这些元组中的索引作为它们的参数。


  现在我们可以理解hello()函数的字节码列表了:


  LOAD_GLOBAL0:告诉Python在co_names(打印函数)的索引0处通过引用的名称找到全局对象,并将其推入执行栈。


  LOAD_CONST1:取出co_const的索引1处的文字常量,推送到堆栈上(co_const中索引0处的值为None,因为如果Python函数中没有显式的返回表达式,会隐式调用,返回值为None)


  CALL_FUNCTION1:告诉Python调用一个函数;它需要从堆栈中弹出一个位置参数,然后新堆栈的顶部将是要调用的函数。


  “原始”字节码——不可读的字节码——可以通过代码对象的co_code属性来访问。如果想尝试手动反汇编函数,可以使用listdis.opname从十进制字节值中找到对应的字节码指令的名称。


  python字节码怎么用?


  现在你学了这么多,你可能会想:“嗯,我想这很酷,但是知道这些有什么实际用途呢?”除了简单地满足好奇心之外,从以下几个方面理解Python字节码也很有用。


  首先,理解Python的执行模型可以帮助您理解您的代码。人们喜欢开玩笑说C是一种“可移植汇编程序”,你可以猜C语言源代码会翻译成哪些机器指令。对于Python来说,理解字节码也有类似的效果——如果你能预测Python源代码会转换成什么字节码,你就能更好的决定如何编写和优化。


  其次,理解字节码对于回答一些关于Python的问题很有帮助。比如我经常看到Python新手程序员疑惑为什么有些结构比其他的快(比如为什么{}比dict()快)。知道如何访问和读取Python字节码可以帮助你找到答案(试试:dis.dis(“{}”)和dis.dis(“dict()”)。


  最后,理解字节码以及Python如何执行它,为不常参与特定类型编程(面向堆栈的编程)的Python程序员提供了一个有用的视角。如果您曾经使用过像FORTH或Factor这样的面向堆栈的语言,这可能不是什么新鲜事,但是如果您以前没有接触过这些编程方法,那么了解Python字节码及其面向堆栈的编程模型是扩展和提高您的编程知识的好方法。


  了解Python字节码更多信息的资源在哪里?


  如果你想了解更多关于Python字节码、Python虚拟机以及它们是如何工作的,我推荐以下资源:


  由ObiIke-Nwosu编写的《InsidethePythonVirtualMachine》是一本免费的在线书籍,深入探究了Python解释器,详细解释了Python实际上是如何工作的。


  python中的Apython解释器written是由AllisonKapturt编写的。是用Python构建Python字节码解释器的教程,完全实现了运行Python字节码的虚拟机。


  最后,CPython解释器是开源的,可以在GitHub上查看。字节码解释器的实现位于Python/ceval.c中这里是Python3.6.4版本3.6.4的文件;字节码指令由第1266行的switch语句处理。


  恭喜你读了这篇文章。其实写这篇文章的目的就是给你一点指导。你需要自己了解更多关于python字节码的知识。如果你有更多关于python的问题,欢迎来东软瑞道python培训学院咨询。



  • 友情链接

关注东软睿道公众号了解更多IT行业资讯

添加东小萌微信
获取更多IT学习资源