如何在Python 3中找到.pyc标头的幻数

sep*_*p2k 13 python pyc python-3.x

Python字节码(.pyc)文件有一个标题,以在Python版本之间更改的幻数开头.我如何(以编程方式)找出当前Python版本的数字以生成有效的标头?我目前正在为Python 3.7.1编写硬编码,但这意味着我现在依赖于特定的Python版本.

这个答案完全符合我的要求py_compile.MAGIC,但在Python 3中似乎不再存在.如何在Python 3中完成相同的操作?

这是我正在尝试做的一个例子:

import dis
import marshal

PYC_HEADER = b'\x42\x0d\x0d\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

def f():
    print('Hello World')

with open('test.pyc', 'wb') as pyc:
    pyc.write(PYC_HEADER)
    marshal.dump(dis.Bytecode(f).codeobj, pyc)
Run Code Online (Sandbox Code Playgroud)

这应该创建一个文件test.pyc,然后可以使用与脚本相同的Python解释器运行,并且应该打印"Hello World!".它确实如此,但只有在使用Python 3.7时才会这样.我正在寻找一种方法来生成用于运行脚本的Python 3版本的标头,而不是硬编码3.7.

对于上下文:

我正在编写一个简单的编程语言到不同的字节码格式(LLVM,Java字节码,Web汇编和现在的Python字节码),作为计划编译的计划教程系列的一部分.

我可以使用byteasm库生成Python字节码,这给了我一个函数作为结果.但是为了将内容写入.pyc文件,我需要一个有效的头.通过对头文件进行硬编码,只有遵循本教程的人员运行与我相同版本的Python 3(3.7)或者他们必须手动找到其版本的幻数时,代码才会起作用.

kal*_*ann 9

从Python 3.4开始importlib.util.MAGIC_NUMBER,模块中有importlib:

>>> import importlib
>>> importlib.util.MAGIC_NUMBER.hex()
'420d0d0a'
Run Code Online (Sandbox Code Playgroud)

Python <3.4或Python2的另一个解决方案是模块get_magic方法imp.

>>> import imp
>>> imp.get_magic().hex()
'420d0d0a'
Run Code Online (Sandbox Code Playgroud)

请注意,虽然这在Python 3.7中仍然有效,但自Python 3.4以来已弃用


Jos*_*Lee 8

它感动了!1

>>> import importlib.util
>>> importlib.util.MAGIC_NUMBER
b'3\r\r\n'
Run Code Online (Sandbox Code Playgroud)

版本3.4中的新功能.

可能最简单的方法是将它包装在试一试/除了回归之外py_compile.

  • 我认为你的意思是"尝试/除了"而不是"尝试/捕获";) (2认同)
  • 哈,javascript太多了 (2认同)