2013-10-24 12 views
15

Tôi gặp rất nhiều khó khăn khi hiểu mã bytecode của Python và mô-đun dis của Python.Làm thế nào để đọc mã bytecode python?

import dis 
def func(): 
    x = 1 
dis.dis(func) 

Đoạn mã trên khi gõ vào trình biên dịch tạo ra kết quả như sau:

0 LOAD_CONST     1(1) 
    3 STORE_FAST     0(x) 
    6 LOAD_CONST     0(NONE) 
    9 RETURN_VALUE 

Ví dụ:

ý nghĩa của LOAD_CONST, STORE_FAST và những con số như 0 là gì, 3 , 69?

Tài nguyên cụ thể, nơi tôi có thể tìm thấy thông tin này sẽ được nhiều người đánh giá cao.

+0

Tôi không chắc chắn nếu bạn đọc câu trả lời này http://stackoverflow.com/a/12673195/973699 – DevC

+0

@DevC Tôi đã đọc câu hỏi này, nhưng vấn đề là tôi chỉ muốn một lời giải thích cho một chức năng rất "đơn giản" , giống như cái tôi đã đề cập trong câu hỏi của mình, để ít nhất tôi có thể có được một ý tưởng nhỏ về chính xác những gì đang xảy ra trong mã byte. –

Trả lời

29

Những con số trước khi bytecode là offsets vào bytecode nhị phân ban đầu:

>>> func.__code__.co_code 
'd\x01\x00}\x00\x00d\x00\x00S' 

Một số bytecode đi kèm với thông tin bổ sung (arguments) ảnh hưởng thế nào mỗi bytecode công trình, bù đắp cho bạn vào những gì vị trí trong bytestream mã bytecode đã được tìm thấy.

Bytecode LOAD_CONST bytecode (ASCII d, hex 64) được theo sau bởi hai byte bổ sung mã hóa tham chiếu đến một hằng số được liên kết với bytecode, ví dụ. Kết quả là, mã vạch STORE_FAST (ASCII }, hex 7D) được tìm thấy tại chỉ mục 3.

dis module documentation liệt kê ý nghĩa của từng lệnh. Đối với LOAD_CONST, nó cho biết:

Đẩy co_consts[consti] vào ngăn xếp.

liên quan đến cấu trúc co_consts luôn có mặt với đối tượng mã; trình biên dịch xây dựng rằng:

>>> func.__code__.co_consts 
(None, 1) 

Các tải opcode chỉ số 1 từ cấu trúc đó (01 00 byte trong mã hóa bytecode 1), và dis đã nhìn thấy video giúp bạn; nó là giá trị 1.

Các lệnh kế tiếp, STORE_FAST được mô tả như sau:

Stores TOS vào địa phương co_varnames[var_num].

Ở đây TOS là Top of Stack; lưu ý rằng LOAD_CONST chỉ cần đẩy thứ gì đó vào ngăn xếp, giá trị 1. co_varnames là một cấu trúc khác; nó tham chiếu tên biến địa phương, các tài liệu tham khảo opcode chỉ số 0:

>>> func.__code__.co_varnames 
('x',) 

dis nhìn mà lên quá, và tên bạn sử dụng trong mã của bạn là x.Do đó, mã opcode này được lưu trữ 1 vào x.

Một LOAD_CONST tải None vào stack từ chỉ số 0, tiếp theo là RETURN_VALUE:

Returns với TOS cho người gọi của hàm.

để hướng dẫn này chiếm phần trên cùng của ngăn xếp (có hằng số None) và trả về từ khối mã này. None là giá trị trả về mặc định cho các hàm không có tuyên bố rõ ràng return.

Bạn bỏ qua một cái gì đó từ dis đầu ra, số dòng:

>>> dis.dis(func) 
    2   0 LOAD_CONST    1 (1) 
       3 STORE_FAST    0 (x) 
       6 LOAD_CONST    0 (None) 
       9 RETURN_VALUE   

Lưu ý 2 trên dòng đầu tiên; đó là số dòng trong nguồn gốc chứa mã Python đã được sử dụng cho các hướng dẫn này. Các đối tượng mã Python có các thuộc tính co_lnotabco_firstlineno cho phép bạn ánh xạ các byte bytecode trở lại số dòng trong nguồn gốc. dis thực hiện điều này cho bạn khi hiển thị việc tháo gỡ.

+0

cảm ơn câu trả lời mở rộng và tham chiếu đến tài liệu –

Các vấn đề liên quan