โมดูล dis ในไลบรารีมาตรฐานของ Python มีฟังก์ชันต่างๆ ที่มีประโยชน์สำหรับการวิเคราะห์ไบต์โค้ดของ Python โดยการดิแอสเซมเบล (disassemble) มันเป็นรูปแบบที่มนุษย์อ่านได้ นี่ช่วยให้ทำการเพิ่มประสิทธิภาพได้ ไบต์โค้ดเป็นรายละเอียดการใช้งานเฉพาะเวอร์ชันของตัวแปล
ฟังก์ชัน dis()
ฟังก์ชัน dis() สร้างการแสดงผลดิแอสเซมเบลของโค้ดต้นทาง Python ใดๆ เช่น โมดูล, คลาส, เมธอด, ฟังก์ชัน, หรืออ็อบเจ็กต์โค้ด:
>>> 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 การวิเคราะห์ไบต์โค้ดถูกกำหนดในคลาส Bytecode คอนสตรัคเตอร์คืนค่าอ็อบเจ็กต์ Bytecode ซึ่งมีเมธอดต่อไปนี้สำหรับวิเคราะห์ไบต์โค้ด:
Bytecode()
นี่คือคอนสตรัคเตอร์ วิเคราะห์ไบต์โค้ดที่สอดคล้องกับฟังก์ชัน, เจเนอเรเตอร์, เมธอด, สตริงโค้ดต้นทาง, หรืออ็อบเจ็กต์โค้ด นี่เป็นวอร์ปเปอร์ที่สะดวกสำหรับฟังก์ชันหลายตัว:
>>> 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()
ฟังก์ชันนี้คืนค่าข้อมูลของอ็อบเจ็กต์โค้ด Python:
>>> dis.code_info(hello) "Name: hello\nFilename:\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()
ฟังก์ชันนี้พิมพ์ข้อมูลโค้ดโดยละเอียดของโมดูล, ฟังก์ชัน หรือคลาส Python:
>>> dis.show_code(hello) Name: hello Filename: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
disassemble()
ฟังก์ชันนี้ดิแอสเซมเบลอ็อบเจ็กต์โค้ดและให้เอาต์พุทแบ่งในคอลัมน์ต่อไปนี้:
หมายเลขบรรทัด สำหรับคำสั่งแรกของแต่ละบรรทัด
คำสั่งปัจจุบัน แสดงด้วย -->
คำสั่งที่มีป้ายกำกับ แสดงด้วย >>
ที่อยู่ของคำสั่ง
ชื่อโค้ดการดำเนินการ (operation code name)
พารามิเตอร์การดำเนินการ
การตีความพารามิเตอร์ในวงเล็บ
>>> codeInString = 'a = 5\nb = 6\nsum = a + b \nprint("sum = ",sum)'
>>> codeObject = compile(codeInString, 'sumstring', 'exec')
>>> dis.disassemble(codeObject)
ผลลัพธ์
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()
ฟังก์ชันนี้คืนค่า iterator บนคำสั่งในฟังก์ชัน, เมธอด, สตริงโค้ดต้นทาง หรืออ็อบเจ็กต์โค้ดที่ให้มา Iterator สร้างชุดของ named tuples Instruction ให้รายละเอียดของแต่ละการดำเนินการในโค้ดที่ให้มา:
>>> it = dis.get_instructions(code)
>>> for i in it:
... print(i)
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=", line 2>, argrepr='", 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)
ข้อมูลฟังก์ชันอยู่ในรูปแบบ tuple-like object พร้อมพารามิเตอร์ดังนี้:
| Instruction | รายละเอียดสำหรับการดำเนินการไบต์โค้ด |
|---|---|
| opcode | รหัสตัวเลขสำหรับการดำเนินการ สอดคล้องกับค่า opcode ที่แสดงด้านล่างและค่าไบต์โค้ดในคอลเลกชัน Opcode |
| opname | ชื่อที่มนุษย์อ่านได้สำหรับการดำเนินการ |
| arg | อาร์กิวเมนต์ตัวเลขสำหรับการดำเนินการ (ถ้ามี) มิฉะนั้น None |
| argval | ค่า arg ที่แก้ไขแล้ว (ถ้ารู้) มิฉะนั้นเหมือน arg |
| argrepr | คำอธิบายที่มนุษย์อ่านได้ของอาร์กิวเมนต์การดำเนินการ |
| offset | ดัชนีเริ่มต้นของการดำเนินการภายในลำดับไบต์โค้ด |
| starts_line | บรรทัดที่เริ่มต้นโดย opcode นี้ (ถ้ามี) มิฉะนั้น None |
| is_jump_target | True หากโค้ดอื่นกระโดดมาที่นี่ มิฉะนั้น False |