python - 给定一个 python .pyc 文件,是否有一个工具可以让我查看字节码?

标签 python bytecode pyc

CPython 解释器会自动将 Python 模块编译成 .pyc 文件。包含字节码的 .pyc 文件是二进制格式(编码代码?)。是否有 GUI(或命令行)工具可以让我查看字节码?

最佳答案

每个 *.pyc 文件都是包含以下内容的二进制文件:

  • 一个四字节的魔数(Magic Number) - 它只是随着编码代码的每次更改而更改的字节;
  • 一个四字节的修改时间戳 - 是生成 .pyc 的源文件的 Unix 修改时间戳,以便在源发生变化时可以重新编译;
  • 从 Python3.3+ 版本开始,接下来的四个字节是将源文件的大小编码为 long 的字段;
  • 一个编码代码对象。

为什么不直接使用 CPython 的内置功能来完成这项任务?


一个文件 view_pyc_file.py

import platform
import time
import sys
import binascii
import marshal
import dis
import struct


def view_pyc_file(path):
    """Read and display a content of the Python`s bytecode in a pyc-file."""

    file = open(path, 'rb')

    magic = file.read(4)
    timestamp = file.read(4)
    size = None

    if sys.version_info.major == 3 and sys.version_info.minor >= 3:
        size = file.read(4)
        size = struct.unpack('I', size)[0]

    code = marshal.load(file)

    magic = binascii.hexlify(magic).decode('utf-8')
    timestamp = time.asctime(time.localtime(struct.unpack('I', timestamp)[0]))

    dis.disassemble(code)

    print('-' * 80)
    print(
        'Python version: {}\nMagic code: {}\nTimestamp: {}\nSize: {}'
        .format(platform.python_version(), magic, timestamp, size)
    )

    file.close()


if __name__ == '__main__':
    view_pyc_file(sys.argv[1])

使用下一个 CPython 版本进行测试:

  • 2.7.9
  • 3.4.2
  • 3.5.2

演示

文件main.py的内容

$ cat main.py
print("Never give up")

python2.7创建并读取pyc文件

setivolkylany$~/Downloads/temp/temp$ python2.7 -m py_compile main.py 
setivolkylany$~/Downloads/temp/temp$ python2.7 view_pyc_file.py ./main.pyc
  1           0 LOAD_CONST               0 ('Never give up')
              3 PRINT_ITEM          
              4 PRINT_NEWLINE       
              5 LOAD_CONST               1 (None)
              8 RETURN_VALUE        
--------------------------------------------------------------------------------
Python version: 2.7.9
Magic code: 03f30d0a
Timestamp: Fri Mar 10 15:08:20 2017
Size: None

python3.4创建并读取pyc文件

setivolkylany$~/Downloads/temp/temp$ python3.4 -m py_compile main.py 
setivolkylany$~/Downloads/temp/temp$ python3.4 view_pyc_file.py __pycache__/main.cpython-34.pyc 
  1           0 LOAD_NAME                0 (print)
              3 LOAD_CONST               0 ('Never give up')
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
              9 POP_TOP
             10 LOAD_CONST               1 (None)
             13 RETURN_VALUE
--------------------------------------------------------------------------------
Python version: 3.4.2
Magic code: ee0c0d0a
Timestamp: Fri Mar 10 15:08:20 2017
Size: 23

python3.5创建并读取pyc文件

setivolkylany$~/Downloads/temp/temp$ python3.5 -m py_compile main.py 
setivolkylany$~/Downloads/temp/temp$ python3.5 view_pyc_file.py __pycache__/main.cpython-35.pyc 
  1           0 LOAD_NAME                0 (print)
              3 LOAD_CONST               0 ('Never give up')
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
              9 POP_TOP
             10 LOAD_CONST               1 (None)
             13 RETURN_VALUE
--------------------------------------------------------------------------------
Python version: 3.5.2
Magic code: 160d0d0a
Timestamp: Fri Mar 10 15:08:20 2017
Size: 23

基于:

关于python - 给定一个 python .pyc 文件,是否有一个工具可以让我查看字节码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11141387/

相关文章:

python - 绘制 For 迭代的结果

python - DBSCAN sklearn 非常慢

java - 用于方法入口/导出的 ASM 字节码检测

java - JVM指令-sload

Python 回溯损坏 : code out of sync with what is executed?

python - 在Python中合并2个字典

python - 使用 Python 将 CSV 元素从列合并到行

Java 32 位和 64 位

jython - 如何控制 $py.class 文件的去向?

python - 如果解释了Python,那么什么是.pyc文件?