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

发布于 2024-12-10 16:33:10 字数 55 浏览 0 评论 0原文

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

Is there any way to know by which Python version the .pyc file was compiled?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

月隐月明月朦胧 2024-12-17 16:33:10

.pyc 文件的前两个字节是表示字节码版本的幻数。该单词以小端格式存储,已知值为:

Python 版本十进制 十六进制注释
Python 1.5201210x994e
Python 1.5.1201210x994e
Python 1.5.2201210x994e
Python 1.6504280x4cc4
Python 2.0508230x87c6
Python 2.0.1508230x87c6
Python 2.1602020x2aeb
Python 2.1.1602020x2aeb
Python 2.1.2602020x2aeb
Python 2.2607170x2ded
Python 2.3a0620110x3bf2
Python 2.3a0620210x45f2
Python 2.3a0620110x3bf2
Python 2.4a0620410x59f2
Python 2.4a3620510x63f2
Python2.4b1 620610x6df2
Python 2.5a0620710x77f2
Python 2.5a0620810x81f2ast分支
Python 2.5a0620910x8bf2with
Python 2.5a0620920x8cf2更改 WITH_CLEANUP 操作码
Python 2.5b3621010x95f2修复错误代码:for x, in ...
Python 2.5 b3621110x9ff2修复错误代码:x +=yield
Python 2.5c1621210xa9f2使用 for 循环修复错误的 lnotab 并存储本应删除的常量
Python 2.5c2621310xb3f2修复错误的代码:for x, in ... in listcomp/genexp
Python 2.6a0621510xc7f2窥孔优化和STORE_MAP 操作码
Python 2.6a1621610xd1f2WITH_CLEANUP 优化
Python 2.7a0621710xdbf2优化列表推导/更改 LIST_APPEND
Python 2.7a0621810xe5f2优化条件分支:介绍POP_JUMP_IF_FALSEPOP_JUMP_IF_TRUE
Python 2.7a0621910xeff2介绍 SETUP_WITH
Python 2.7a0622010xf9f2介绍 BUILD_SET
Python 2.7a0622110x03f3介绍MAP_ADDSET_ADD
Python 300030000xb80b
30100xc20b已删除 UNARY_CONVERT
第3020章0xcc0b添加了BUILD_SET
30300xd60b添加仅关键字参数
30400xe00b添加签名注释
30500xea0bprint 成为函数
30600xf40bPEP 3115 元类语法
30610xf50b字符串文字变为 unicode
30710xff0bPEP 3109 引发更改
30810x090cPEP 3137 make __file____name__ unicode
30910x130cKill str8 interning
31010x1d0c从 2.6a0 合并,参见 62151
31030x1f0c__file__ 指向源文件
Python 3.0a431110x270cWITH_CLEANUP 优化
Python 3.0a531310x3b0c词法异常堆栈,包括 POP_EXCEPT
Python 3.1a031410x450c优化列表、集合和字典推导式:更改 LIST_APPENDSET_ADD,添加MAP_ADD
Python 3.1a031510x4f0c优化条件分支:引入POP_JUMP_IF_FALSEPOP_JUMP_IF_TRUE
Python 3.2a031600x580c添加SETUP_WITH,标签: cpython-32
Python 3.2a131700x620c添加 DUP_TOP_TWO,删除 DUP_TOPXROT_FOUR,标签:cpython-32
Python 3.2a231800x6c0c添加 DELETE_DEREF

来源:

  • Python/import.c - 由 aix 合并Python 2.7.2 和 Python 3.2.2
  • Little endian 十六进制值,用于比较 jimbob 添加的 Igor Popov 方法的前两个字节

The first two bytes of the .pyc file are the magic number that tells the version of the bytecodes. The word is stored in little-endian format, and the known values are:

Python versionDecimalHexadecimalComment
Python 1.5201210x994e
Python 1.5.1201210x994e
Python 1.5.2201210x994e
Python 1.6504280x4cc4
Python 2.0508230x87c6
Python 2.0.1508230x87c6
Python 2.1602020x2aeb
Python 2.1.1602020x2aeb
Python 2.1.2602020x2aeb
Python 2.2607170x2ded
Python 2.3a0620110x3bf2
Python 2.3a0620210x45f2
Python 2.3a0620110x3bf2!
Python 2.4a0620410x59f2
Python 2.4a3620510x63f2
Python 2.4b1620610x6df2
Python 2.5a0620710x77f2
Python 2.5a0620810x81f2ast-branch
Python 2.5a0620910x8bf2with
Python 2.5a0620920x8cf2changed WITH_CLEANUP opcode
Python 2.5b3621010x95f2fix wrong code: for x, in ...
Python 2.5b3621110x9ff2fix wrong code: x += yield
Python 2.5c1621210xa9f2fix wrong lnotab with for loops and storing constants that should have been removed
Python 2.5c2621310xb3f2fix wrong code: for x, in ... in listcomp/genexp
Python 2.6a0621510xc7f2peephole optimizations and STORE_MAP opcode
Python 2.6a1621610xd1f2WITH_CLEANUP optimization
Python 2.7a0621710xdbf2optimize list comprehensions/change LIST_APPEND
Python 2.7a0621810xe5f2optimize conditional branches: introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE
Python 2.7a0621910xeff2introduce SETUP_WITH
Python 2.7a0622010xf9f2introduce BUILD_SET
Python 2.7a0622110x03f3introduce MAP_ADD and SET_ADD
Python 300030000xb80b
30100xc20bremoved UNARY_CONVERT
30200xcc0badded BUILD_SET
30300xd60badded keyword-only parameters
30400xe00badded signature annotations
30500xea0bprint becomes a function
30600xf40bPEP 3115 metaclass syntax
30610xf50bstring literals become unicode
30710xff0bPEP 3109 raise changes
30810x090cPEP 3137 make __file__ and __name__ unicode
30910x130ckill str8 interning
31010x1d0cmerge from 2.6a0, see 62151
31030x1f0c__file__ points to source file
Python 3.0a431110x270cWITH_CLEANUP optimization
Python 3.0a531310x3b0clexical exception stacking, including POP_EXCEPT
Python 3.1a031410x450coptimize list, set and dict comprehensions: change LIST_APPEND and SET_ADD, add MAP_ADD
Python 3.1a031510x4f0coptimize conditional branches: introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE
Python 3.2a031600x580cadd SETUP_WITH, tag: cpython-32
Python 3.2a131700x620cadd DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR, tag: cpython-32
Python 3.2a231800x6c0cadd DELETE_DEREF

Sources:

  • Python/import.c - merged by aix from Python 2.7.2 and Python 3.2.2
  • Little endian hex values for comparison first two bytes of Igor Popov's method added by jimbob
最后的乘客 2024-12-17 16:33:10

您可以按如下方式获取 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'

通过比较幻数,您将知道生成 pyc 文件的 python 版本。

You can get the magic number of your Python as follows:

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

To get the magic number for a pyc file you can do the following:

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

By comparing the magic numbers you'll know the python version that generated the pyc file.

十秒萌定你 2024-12-17 16:33:10

或者,如果您有 GNU/Linux 系统,您可以在终端中使用命令“file”:

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

Or, if you have a GNU/Linux system you can use the command "file" in a terminal:

$ file code.pyc
> code.pyc: python 3.5.2 byte-compiled
小ぇ时光︴ 2024-12-17 16:33:10

看一下我的 Python 脚本,它检测并返回文件所使用的 Python 版本(*.pyc 或 *.pyo)已编译。

它检测从 Python 1.5 到最新 Python 3 版本的 Python 版本。

Take a look at my script in Python that detects and returns the version of Python by which the file (*.pyc or *.pyo) was compiled.

It detects versions of Python from Python 1.5 up to last Python 3 build.

陌路终见情 2024-12-17 16:33:10

官方 Python github 存储库似乎不再将列表保留在 import.c 中。

在搜索比我在其他地方找到的更新的列表时,我遇到了似乎是 Google 截至 2017 年 5 月的最新列表。

https://github.com/google/pytype/blob/master/pytype/pyc/magic.py

The official Python github repository no longer appears to keep the list in import.c.

When searching for a more current list than I could find elsewhere, I encountered what appears to be an up-to-date list from Google as of May 2017.

https://github.com/google/pytype/blob/master/pytype/pyc/magic.py

橘和柠 2024-12-17 16:33:10

添加@Igor Popov 的答案。

要从较新版本的 Python 检查已编译脚本的版本:

# written in python3

filename = "outfit.cpython-39.pyc"

with open(filename,'rb') as f:
    magic = f.read(4)

print(int.from_bytes(magic[:2], 'little'))

您可以在此处查找输出编号:
https://github.com/google/pytype/blob/主/pytype/pyc/magic.py

Adding to @Igor Popov's answer.

To check the version of the compiled script from a newer version of Python:

# written in python3

filename = "outfit.cpython-39.pyc"

with open(filename,'rb') as f:
    magic = f.read(4)

print(int.from_bytes(magic[:2], 'little'))

You can lookup the output number here:
https://github.com/google/pytype/blob/master/pytype/pyc/magic.py

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文