令人惊讶的是,是的——有点。
但是,您需要了解许多注意事项。第一个需要注意的是,Python 字节码以及扩展的汇编指令可以更改每个版本。要理解的第二个警告是,简单地发出的信息dis.dis()
文本形式对于 Python 解释器的需求来说是不完整的。因此,您需要一种方法来填充缺失的信息。
我写了一个字节码汇编器 https://pypi.org/project/xasm/它将类似于上面的文本文件程序集转换为 python 字节码。
在您的示例中,您有一个代码对象,而不是创建字节码文件所需的完整信息,但是xasm
当然,在使用字节码文件中所需的附加信息写出代码对象之前,先创建代码对象。这是在函数中完成的create_code()
of https://github.com/rocky/python-xasm/blob/master/xasm/assemble.py https://github.com/rocky/python-xasm/blob/master/xasm/assemble.py
为了了解代码对象中的内容以及它如何适合 Python 字节码文件之间的区别,我将使用您的示例,然后完成如何创建字节码文件。
如果我在 Python 3.6.10 中运行你的示例,我会得到:
1 0 LOAD_NAME 0 (print)
2 LOAD_CONST 0 ('lol')
4 CALL_FUNCTION 1
6 POP_TOP
8 LOAD_CONST 1 (None)
10 RETURN_VALUE
但是如果我将你的 Python 代码放入一个文件中,比如说foo.py
,使用字节编译它py_compile.compile(source, bytecode, source)
和使用xdis https://pypi.org/project/xdis/的跨版本Python反汇编器pydisasm
I get:
# pydisasm version 4.2.4
# Python bytecode 3.6 (3379)
# Disassembled from Python 3.6.10 (default, Jan 23 2020, 16:43:38)
# [GCC 7.4.0]
# Timestamp in code: 1586703495 (2020-04-12 10:58:15)
# Source code size mod 2**32: 13 bytes
# Method Name: <module>
# Filename: foo.py
# Argument count: 0
# Kw-only arguments: 0
# Number of locals: 0
# Stack size: 2
# Flags: 0x00000040 (NOFREE)
# First Line: 1
# Constants:
# 0: 'lol'
# 1: None
# Names:
# 0: print
1: 0 LOAD_NAME 0 (print)
2 LOAD_CONST 0 ('lol')
4 CALL_FUNCTION 1
6 POP_TOP
8 LOAD_CONST 1 (None)
10 RETURN_VALUE
请注意,在字节码文件中,有一些严格意义上不属于代码对象的附加信息:
- 正在使用哪个字节码(3.6,幻数 3379),
- 创建代码的时间戳,
- 源代码的大小 (mod 2**32),
- 方法名称,
- 一个文件名,
- 代码的参数,
- 方法标志,以及
- 各种名称:常量、变量。
现在让我们把它放到一个文件中,比如foo2.pyasm
。要将其写入字节码文件,只需运行pyc-xasm
:
$ pyc-xasm foo2.pyasm
Wrote foo2.pyc
$ python foo2.pyc
lol
我在我的作品中演示了所有这一切PyColumbia 2018 的 2018 年照明演讲 https://rocky.github.io/pycon2018-light.co/
我应该注意,直到下一个版本xasm
and xdis
,Python 3.7 及更高版本不起作用,但 3.6 及更早版本可以。 罢工>