可以从脚本执行 Python 字节码吗?

Possible to execute Python bytecode from a script?

假设我有一个 运行ning CPython 会话,

有没有办法直接从 pyc 文件中 运行 数据 (bytes)? (无需将数据存储在磁盘上,也无需编写临时 pyc 文件)

显示简单用例的示例脚本:

if foo:
    # Intentionally ambiguous, since the data source
    # is a detail and answers shouldn't depend this detail.
    data = read_data_from_somewhere()
else:
    data = open("bar.pyc", 'rb').read()

assert(type(data) is bytes)

code = bytes_to_code(data)

# call a method from the loaded code
code.call_function()

具体使用并不重要,但动态生成代码并通过网络复制执行是一个用例(为了思考这个问题)。


这里有一些示例用例,这让我很想知道如何做到这一点:

假设编译的.pyc平台是正确的,直接导入即可。因此,对于 python 路径中的文件 bar.pyc,即使 bar.py 不存在,以下内容仍然有效:

import bar
bar.call_function()

Is there a way to run the data from a pyc file directly?

编译后的代码object可以使用marshal

保存
import marshal
bytes = marshal.dumps(eggs)

字节可以转换回代码object

eggs = marshal.loads(bytes)
exec(eggs)

一个 pyc 文件是一个编组代码 object 带有 header

对于Python3,header是需要跳过的16个字节,剩余的数据可以通过marshal.loads读取。


Ned Batchelder's blog post:

At the simple level, a .pyc file is a binary file containing only three things:

  • A four-byte magic number,
  • A four-byte modification timestamp, and
  • A marshalled code object.

注意,link 引用 Python2,但在 Python3 中几乎相同,pyc header 大小只是 16 而不是 8字节。