有没有方法知道.pyc文件是由哪个Python版本编译的?

43 投票
6 回答
35675 浏览
提问于 2025-04-17 04:33

有没有办法知道一个 .pyc 文件是用哪个版本的 Python 编译的呢?

6 个回答

17

或者,如果你使用的是GNU/Linux系统,可以在终端里输入“file”这个命令:

$ file code.pyc
> code.pyc: python 3.5.2 byte-compiled
61

.pyc 文件的前两个字节是一个魔法数字,用来表示字节码的版本。这个数字是以小端格式存储的,已知的值如下:

Python 版本 十进制 十六进制 备注
Python 1.5 20121 0x994e
Python 1.5.1 20121 0x994e
Python 1.5.2 20121 0x994e
Python 1.6 50428 0x4cc4
Python 2.0 50823 0x87c6
Python 2.0.1 50823 0x87c6
Python 2.1 60202 0x2aeb
Python 2.1.1 60202 0x2aeb
Python 2.1.2 60202 0x2aeb
Python 2.2 60717 0x2ded
Python 2.3a0 62011 0x3bf2
Python 2.3a0 62021 0x45f2
Python 2.3a0 62011 0x3bf2 !
Python 2.4a0 62041 0x59f2
Python 2.4a3 62051 0x63f2
Python 2.4b1 62061 0x6df2
Python 2.5a0 62071 0x77f2
Python 2.5a0 62081 0x81f2 ast-branch
Python 2.5a0 62091 0x8bf2 with
Python 2.5a0 62092 0x8cf2 更改了 WITH_CLEANUP 操作码
Python 2.5b3 62101 0x95f2 修复错误代码: for x, in ...
Python 2.5b3 62111 0x9ff2 修复错误代码: x += yield
Python 2.5c1 62121 0xa9f2 修复错误的 lnotab,涉及 for 循环和应该被移除的常量存储
Python 2.5c2 62131 0xb3f2 修复错误代码: for x, in ... 在列表推导/生成表达式中
Python 2.6a0 62151 0xc7f2 进行 peephole 优化和 STORE_MAP 操作码
Python 2.6a1 62161 0xd1f2 WITH_CLEANUP 优化
Python 2.7a0 62171 0xdbf2 优化列表推导/更改 LIST_APPEND
Python 2.7a0 62181 0xe5f2 优化条件分支: 引入 POP_JUMP_IF_FALSEPOP_JUMP_IF_TRUE
Python 2.7a0 62191 0xeff2 引入 SETUP_WITH
Python 2.7a0 62201 0xf9f2 引入 BUILD_SET
Python 2.7a0 62211 0x03f3 引入 MAP_ADDSET_ADD
Python 3000 3000 0xb80b
3010 0xc20b 移除 UNARY_CONVERT
3020 0xcc0b 添加 BUILD_SET
3030 0xd60b 添加仅关键字参数
3040 0xe00b 添加签名注解
3050 0xea0b print 变成了一个函数
3060 0xf40b PEP 3115 元类语法
3061 0xf50b 字符串字面量变成了 Unicode
3071 0xff0b PEP 3109 抛出变化
3081 0x090c PEP 3137 使 __file____name__ 成为 Unicode
3091 0x130c 移除 str8 共享
3101 0x1d0c 从 2.6a0 合并,见 62151
3103 0x1f0c __file__ 指向源文件
Python 3.0a4 3111 0x270c WITH_CLEANUP 优化
Python 3.0a5 3131 0x3b0c 词法异常堆栈,包括 POP_EXCEPT
Python 3.1a0 3141 0x450c 优化列表、集合和字典推导: 更改 LIST_APPENDSET_ADD,添加 MAP_ADD
Python 3.1a0 3151 0x4f0c 优化条件分支: 引入 POP_JUMP_IF_FALSEPOP_JUMP_IF_TRUE
Python 3.2a0 3160 0x580c 添加 SETUP_WITH,标签: cpython-32
Python 3.2a1 3170 0x620c 添加 DUP_TOP_TWO,移除 DUP_TOPXROT_FOUR,标签: cpython-32
Python 3.2a2 3180 0x6c0c 添加 DELETE_DEREF

来源:

  • Python/import.c - 由 aix 从 Python 2.7.2 和 Python 3.2.2 合并
  • Igor Popov 方法的前两个字节的小端十六进制值由 jimbob 添加以供比较
58

你可以通过下面的方法找到你使用的Python的魔法数字:

$ python -V
Python 2.6.2
# python
>>> import imp
>>> imp.get_magic().encode('hex')
'd1f20d0a'

如果你想获取一个pyc文件的魔法数字,可以这样做:

>>> f = open('test25.pyc')
>>> magic = f.read(4)
>>> magic.encode('hex')
'b3f20d0a'
>>> f = open('test26.pyc')
>>> magic = f.read(4)
>>> magic.encode('hex')
'd1f20d0a'

通过比较这些魔法数字,你就能知道是哪个版本的Python生成了这个pyc文件。

撰写回答