Python 中的代码对象 code object 与 __code__ 属性

本文探讨Python中的代码对象,它是可执行代码的内部表示,涉及函数、模块和类等。代码对象包含指令和额外信息,用于驱动虚拟机执行。文章通过实例解释了如何访问和理解代码对象的属性,如字节码、常量、局部变量和作用域信息。
摘要由CSDN通过智能技术生成

Python 中的代码对象 code object__code__ 属性



0. 参考资料


1. 概念

代码对象 code object 是一段可执行的 Python 代码在 CPython 中的内部表示。
可执行的 Python 代码包括:

  • 函数
  • 模块
  • 生成器表达式

当你运行一段代码时,它被解析并编译成代码对象,随后被 CPython 虚拟机执行。
代码对象包含一系列直接操作虚拟机内部状态的指令。
这跟你在用 C 语言编程时是类似的,你写出人类可读的文本,然后用编译器转换成二进制形式,二进制代码(C 的机器码或者是 Python 的字节码)被 CPU(对于 C 语言来说)或者 CPython 虚拟机虚拟的 CPU 直接执行。

代码对象除了包含 指令,还提供了虚拟机运行代码所需要的一些 额外信息


2. 探索

以下的内容是在 Python 3.7 中实验的,而且主要是针对于函数来讲。至于模块和类虽然也是通过代码对象实现的(实际上,.pyc 文件里面就存放着序列化的模块代码对象),但是代码对象的大多数特性主要和函数相关。

关于版本需要注意两点:

  • Python 2 中,函数的代码对象通过 函数.func_code 来访问;而 Python 3 中,则需要通过 函数.__code__ 来访问。
  • Python 3 的代码对象增加了一个新属性 co_kwonlyargcount,对应强制关键字参数 keyword-only argument

首先在控制台找出属于 函数.__code__ 的所有不以双下划线开头的属性,一共有 15 个。

>>> li = [i for i in dir((lambda: 0).__code__) if not i.startswith('__')]
>>> print(li)
['co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
>>> len(li)
15

以下内容来自官方文档:

属性 描述
co_argcount number of arguments (not including keyword only arguments, * or ** args)
co_code string of raw compiled bytecode
co_cellvars tuple of names of cell variables (referenced by containing scopes)
co_consts tuple of constants used in the bytecode
co_filename name of file in which this code object was created
co_firstlineno number of first line in Python source code
co_flags bitmap of CO_* flags, read more here
co_lnotab encoded mapping of line numbers to bytecode indices
co_freevars tuple of names of free variables (referenced via a function’s closure)
co_kwonlyargcount number of keyword only arguments (not including ** arg)
co_name name with which this code object was defined
co_names tuple of names of local variables
co_nlocals number of local variables
co_stacksize virtual machine stack space required
co_varnames tuple of names of arguments and local variables

下面逐个解释:

  • co_argcount:函数接收参数的个数,不包括 *args**kwargs 以及强制关键字参数。
>>> def test(a, b, c, d=1, e=2, *args, f=3, g, h=4, **kwargs):
...     print(a, b, c, d, e, f, g, h, args, kwargs)
... 
>>> code_obj = test.__code__
>>> code_obj.co_argcount
5
  • co_code:二进制格式的字节码 bytecode,以字节串 bytes 的形式存储(在 Python 2 中以 str 类型存储)。它为虚拟机提供一系列的指令。函数从第一条指令开始执行,在碰到 RETURN_VALUE 指令的时候停止执行。

其他字节码指令 bytecode instruction 请参阅官方文档:
Python Bytecode Instructions

字节码中每个指令所占字节数是不一样的。
每条指令都有一个操作码 opcode,它指明了虚拟机需要进行的操作,还有一个可选的参数,这个参数是一个整数。
操作码 opcode 是单字节的整数,所以最多有 256 个不同的操作码,尽管其中很多没有被用到。
每个操作码都有名字,在 dis 模块的 dis 函数的输出中可以见到,同时它们在 opcode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值