You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.11中CodeType构造为何会修改输入的co_code?

Python 3.11中CodeType构造函数修改co_code的原因解析

问题场景

在Python 3.11中手动构造修改了co_code的代码对象时,发现types.CodeType构造函数会修改传入的co_code参数,最终生成的代码对象的co_code与输入不一致。示例代码及输出如下:

示例代码

import types
import random

def f(a):
    a = a + 1
    return a

codeobj = f.__code__

new_co_code = bytes([random.randint(0, 255) for _ in range(24)])
new_code = types.CodeType(
    codeobj.co_argcount,
    codeobj.co_posonlyargcount,  
    codeobj.co_kwonlyargcount,
    codeobj.co_nlocals,
    codeobj.co_stacksize,
    codeobj.co_flags,
    new_co_code,
    codeobj.co_consts,
    codeobj.co_names,
    codeobj.co_varnames,
    codeobj.co_filename,
    codeobj.co_name,
    codeobj.co_qualname,
    codeobj.co_firstlineno,
    codeobj.co_lnotab,
    codeobj.co_exceptiontable,
)

print(new_co_code)
print(new_code.co_code)

# 该断言通常会失败
assert new_co_code == new_code.co_code

示例输出

b'\xe6\x8f\xdb\xc8\xb8\xb86\xe6&a\x18\xfb\x11&\xbc\xce\xc0A\xedjg\x8a\xa4G'
b'\x00\x8f\x00\xc8\x00\xb86\xe6\x8ca\xab\xfb\x00\x00\x00\x00\x00\x00\x00\x00g\x8a\xa4G'

原因解析

这种修改行为源于Python 3.11引入的**自适应解释器(Specializing Adaptive Interpreter)**机制,构造CodeType对象时,解释器会对传入的字节码做预处理优化,具体包括:

  • 操作数窄化:Python 3.11调整了部分字节码的操作数长度,将原本2字节的宽操作数指令转换为1字节的窄操作数版本,减少内存占用并提升执行效率。
  • 无效字节填充:对于不符合字节码格式规范的输入(比如随机生成的无效字节),解释器会用0x00填充对齐,避免后续执行时出现更严重的错误。
  • 性能监控补丁:自适应解释器需要在字节码中插入一些用于监控执行情况的标记,这也会修改原始字节码。

即使传入的字节码是无效的(比如示例中的随机字节),解释器仍会执行这些预处理步骤,目的是让字节码尽可能符合自适应解释器的执行规范,哪怕最终执行该代码对象会触发段错误。

相关参考

这部分属于CPython的内部实现细节,官方公开文档中没有详细说明,但可以通过以下途径了解:

  • 查看CPython源代码中Objects/codeobject.c文件的PyCode_NewWithPosOnlyArgs函数,其中包含字节码预处理的逻辑。
  • PEP 659《Specializing Adaptive Interpreter》介绍了自适应解释器的整体设计,可作为背景知识参考。

内容的提问来源于stack exchange,提问作者Abhishek G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 19:59:49