Computer >> Máy Tính >  >> Lập trình >> Python

Disassembler cho Python bytecode

Mô-đun dis trong thư viện chuẩn Python cung cấp các chức năng khác nhau hữu ích để phân tích mã bytecode Python bằng cách tháo rời nó thành một dạng mà con người có thể đọc được. Điều này giúp thực hiện tối ưu hóa. Bytecode là chi tiết triển khai theo phiên bản cụ thể của trình thông dịch.

Hàm

dis ()

Hàm dis () tạo ra biểu diễn được tách rời của bất kỳ nguồn mã Python nào, tức là mô-đun, lớp, phương thức, hàm hoặc đối tượng mã.

>>> def hello():
print ("hello world")
>>> import dis
>>> dis.dis(hello)
2    0 LOAD_GLOBAL 0 (print)
     3 LOAD_CONST 1 ('hello world')
     6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
     9 POP_TOP
     10 LOAD_CONST 0 (None)
     13 RETURN_VALUE

API phân tích Bytecode được định nghĩa trong lớp Bytecode. Hàm tạo của nó trả về đối tượng Bytecode đang có các phương thức sau để phân tích bytecode

Bytecode ()

Đây là hàm tạo. Phân tích mã bytecode tương ứng với một hàm, trình tạo, phương thức, chuỗi mã nguồn hoặc một đối tượng mã. Đây là một trình bao bọc tiện lợi xung quanh nhiều chức năng

>>> string=dis.Bytecode(hello)
>>> for x in string:
      print (x)
Instruction(opname = 'LOAD_GLOBAL', opcode = 116, arg = 0, argval = 'print', argrepr = 'print', offset = 0, starts_line = 2, is_jump_target = False)
Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 1, argval = 'hello world', argrepr = "'hello world'", offset = 3, starts_line = None, is_jump_target = False)
Instruction(opname = 'CALL_FUNCTION', opcode = 131, arg = 1, argval = 1, argrepr = '1 positional, 0 keyword pair', offset = 6, starts_line = None, is_jump_target = False)
Instruction(opname = 'POP_TOP', opcode = 1, arg = None, argval = None, argrepr = '', offset = 9, starts_line = None, is_jump_target = False)
Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 0, argval = None, argrepr = 'None', offset = 10, starts_line = None, is_jump_target = False)
Instruction(opname = 'RETURN_VALUE', opcode = 83, arg = None, argval = None, argrepr = '', offset = 13, starts_line = None, is_jump_target = False)

code_info ()

Hàm này trả về thông tin của đối tượng mã Python.

>>> dis.code_info(hello)
"Name: hello\nFilename: <pyshell#2>\nArgument count: 0\nKw-only arguments: 0\nNumber of locals: 0\nStack size: 2\nFlags: OPTIMIZED, NEWLOCALS, NOFREE\nConstants:\n 0: None\n 1: 'hello world'\nNames:\n 0: print"

show_code ()

Hàm này in thông tin mã chi tiết của mô-đun, hàm hoặc lớp Python.

>>> dis.show_code(hello)
Name: hello
Filename: <pyshell#2>
Argument count: 0
Kw-only arguments: 0
Number of locals: 0
Stack size: 2
Flags: OPTIMIZED, NEWLOCALS, NOFREE
Constants:
   0: None
   1: 'hello world'
Names:
   0: print

Tháo rời ()

Hàm này tách rời một đối tượng mã và đưa ra kết quả được chia thành các cột sau -

  • số dòng, cho lệnh đầu tiên của mỗi dòng

  • hướng dẫn hiện tại, được chỉ ra là ->,

  • một hướng dẫn được gắn nhãn, được chỉ ra bằng>>,

  • địa chỉ của hướng dẫn,

  • tên mã hoạt động,

  • thông số hoạt động và

  • giải thích các tham số trong ngoặc đơn.

>>> codeInString = 'a = 5\nb = 6\nsum = a + b \ nprint("sum = ",sum)'
>>> codeObejct = compile(codeInString, 'sumstring', 'exec')
>>> dis.disassemble(codeObejct)

Đầu ra

1    0 LOAD_CONST 0 (5)
     3 STORE_NAME 0 (a)
2    6 LOAD_CONST 1 (6)
     9 STORE_NAME 1 (b)
3    12 LOAD_NAME 0 (a)
     15 LOAD_NAME 1 (b)
     18 BINARY_ADD
     19 STORE_NAME 2 (sum)
4    22 LOAD_NAME 3 (print)
     25 LOAD_CONST 2 ('sum =')
     28 LOAD_NAME 2 (sum)
     31 CALL_FUNCTION 2 (2 positional, 0 keyword pair)
     34 POP_TOP
     35 LOAD_CONST 3 (None)
     38 RETURN_VALUE

get_instructions ()

Hàm này trả về một trình lặp trên các hướng dẫn trong hàm, phương thức, chuỗi mã nguồn hoặc đối tượng mã được cung cấp. Trình lặp tạo ra một loạt các bộ lệnh có tên Lệnh cung cấp thông tin chi tiết của từng thao tác trong mã được cung cấp.

>>> it=dis.get_instructions(code)
>>> for i in it:
      print (i)
Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 0, argval = <code object hello at 0x02A9BA70,
   file "<disassembly>", line 2>, argrepr = '<code object hello at 0x02A9BA70, file "<disassembly>",
   line 2>', offset = 0, starts_line = 2, is_jump_target = False)
Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 1, argval = 'hello', argrepr = "'hello'", offset = 3, starts_line = None, is_jump_target = False)
Instruction(opname = 'MAKE_FUNCTION', opcode = 132, arg = 0, argval = 0, argrepr = '', offset = 6, starts_line = None, is_jump_target = False)
Instruction(opname = 'STORE_NAME', opcode = 90, arg = 0, argval = 'hello', argrepr = 'hello', offset = 9, starts_line = None, is_jump_target = False)
Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 2, argval = None, argrepr = 'None', offset = 12, starts_line = None, is_jump_target = False)
Instruction(opname = 'RETURN_VALUE', opcode = 83, arg = None, argval = None, argrepr = '', offset = 15, starts_line = None, is_jump_target = False)

Thông tin về các chức năng ở dạng tuple like object với các tham số như hình bên dưới -

Dòng
Hướng dẫn
Chi tiết về hoạt động bytecode
opcode
mã số cho hoạt động, tương ứng với các giá trị opcode được liệt kê bên dưới và các giá trị bytecode trong bộ sưu tập Opcode.
opname
tên người có thể đọc được cho hoạt động
arg
đối số số cho hoạt động (nếu có), nếu không thì không
argval
đã phân giải giá trị đối số (nếu biết), nếu không thì giống như đối số
argrepr
mô tả có thể đọc được của con người về đối số hoạt động
bù đắp
chỉ mục bắt đầu của hoạt động trong chuỗi bytecode
start_line
được bắt đầu bởi opcode này (nếu có), nếu không thì Không
is_jump_target
Đúng nếu mã khác nhảy đến đây, ngược lại Sai