Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

Trượt 1

Show

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

Chương trình chuyên nghiệp theo định hướng công việc đáng tin cậy nhất

Chuyên gia được chứng nhận DevOps (DCP)

Thực hiện bước đầu tiên của bạn vào thế giới của DevOps với khóa học này, điều này sẽ giúp bạn tìm hiểu về các phương pháp và công cụ được sử dụng để phát triển, triển khai và vận hành phần mềm chất lượng cao.

Trượt 2

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

DevOps to DevSecops - Tìm hiểu sự tiến hóa

DevSecops Chứng nhận Chuyên nghiệp (DSOCP)

Học cách tự động hóa bảo mật vào môi trường DevOps có nhịp độ nhanh bằng các công cụ và tập lệnh nguồn mở khác nhau.

Trượt 2

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

DevOps to DevSecops - Tìm hiểu sự tiến hóa

DevSecops Chứng nhận Chuyên nghiệp (DSOCP)

Học cách tự động hóa bảo mật vào môi trường DevOps có nhịp độ nhanh bằng các công cụ và tập lệnh nguồn mở khác nhau.

Trượt 2

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

DevOps to DevSecops - Tìm hiểu sự tiến hóa

DevSecops Chứng nhận Chuyên nghiệp (DSOCP)

Trượt 2

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

DevOps to DevSecops - Tìm hiểu sự tiến hóa

DevSecops Chứng nhận Chuyên nghiệp (DSOCP)

Học cách tự động hóa bảo mật vào môi trường DevOps có nhịp độ nhanh bằng các công cụ và tập lệnh nguồn mở khác nhau.

Được chứng nhận về kỹ năng công nghệ mới để cai trị ngành công nghiệp

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

Kỹ thuật độ tin cậy trang web (SRE) Chứng nhận Chuyên nghiệp

Một phương pháp đo lường và đạt được độ tin cậy thông qua công việc kỹ thuật và hoạt động - được phát triển bởi Google để quản lý dịch vụ.

Thạc sĩ về Kỹ thuật DevOps (MDE)
Interpreter converts the byte code into machine code and sends that machine code to the computer processor for execution.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

Được ghi danh cho khóa học nâng cao nhất và duy nhất trên thế giới có thể khiến bạn trở thành một chuyên gia và kiến ​​trúc sư thành thạo trong các nguyên tắc của DevOps, DevSecops và trang web Kỹ thuật độ tin cậy (SRE) cùng nhau.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

Có được chuyên môn và chứng nhận bản thân

  • Chuyên gia giải pháp Azure DevOps
  • Tìm hiểu về các dịch vụ DevOps có sẵn trên Azure và cách bạn có thể sử dụng chúng để làm cho quy trình làm việc của bạn hiệu quả hơn.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không

Bên trong máy ảo Python

Mua trên Leanpub

Mục lục

    • 1. Giới thiệuIntroduction
    • 2. Quan điểm từ 30.000ftThe View From 30,000ft
    • 3. Biên soạn mã nguồn PythonCompiling Python Source Code
      • 3.1 Từ nguồn này sang cây khácFrom Source To Parse Tree
      • 3.2 Mã thông báo PythonPython tokens
      • 3.3 Từ cây phân tích đến cây cú pháp trừu tượngFrom Parse Tree To Abstract Syntax Tree
      • 3.4 Xây dựng bảng biểu tượngBuilding The Symbol Table
      • 3.5 Từ AST đến mã đối tượngFrom AST To Code Objects
    • 4. Đối tượng PythonPython Objects
      • 4.1 PyobjectPyObject
      • 4.2 Các loại mổ xẻDissecting Types
      • 4.3 Loại nghiên cứu trường hợp đối tượngType Object Case Studies
      • 4.4 Các trường hợp loại tiền khai thácMinting type instances
      • 4.5 Đối tượng và thuộc tính của chúngObjects and their attributes
      • 4.6 Thứ tự phân giải phương pháp (MRO)Method Resolution Order (MRO)
    • 5. Đối tượng mãCode Objects
      • 5.1 Khám phá các đối tượng mãExploring code objects
      • 5.2 Đối tượng mã trong các đối tượng mã khácCode Objects within other code objects
      • 5.3 Đối tượng mã trong VMCode Objects in the VM
    • 6. Các đối tượng khungFrame Objects
      • 6.1 Phân bổ các đối tượng khungAllocating Frame Objects
    • 7. Trình thông dịch và trạng thái chủ đềInterpreter and Thread States
      • 7.1 Trạng thái phiên dịchThe Interpreter state
      • 7.2 Trạng thái chủ đềThe Thread state
    • 8. Intermezzo: Mô -đun
       1     typedef struct _ts {
       2         struct _ts *prev;
       3         struct _ts *next;
       4         PyInterpreterState *interp;
       5 
       6         struct _frame *frame;
       7         int recursion_depth;
       8         char overflowed; 
       9                         
      10         char recursion_critical; 
      11         int tracing;
      12         int use_tracing;
      13 
      14         Py_tracefunc c_profilefunc;
      15         Py_tracefunc c_tracefunc;
      16         PyObject *c_profileobj;
      17         PyObject *c_traceobj;
      18 
      19         PyObject *curexc_type;
      20         PyObject *curexc_value;
      21         PyObject *curexc_traceback;
      22 
      23         PyObject *exc_type;
      24         PyObject *exc_value;
      25         PyObject *exc_traceback;
      26 
      27         PyObject *dict;  /* Stores per-thread state */
      28         int gilstate_counter;
      29 
      30         ... 
      31     } PyThreadState;
      
      05
      Intermezzo: The
       1     typedef struct _ts {
       2         struct _ts *prev;
       3         struct _ts *next;
       4         PyInterpreterState *interp;
       5 
       6         struct _frame *frame;
       7         int recursion_depth;
       8         char overflowed; 
       9                         
      10         char recursion_critical; 
      11         int tracing;
      12         int use_tracing;
      13 
      14         Py_tracefunc c_profilefunc;
      15         Py_tracefunc c_tracefunc;
      16         PyObject *c_profileobj;
      17         PyObject *c_traceobj;
      18 
      19         PyObject *curexc_type;
      20         PyObject *curexc_value;
      21         PyObject *curexc_traceback;
      22 
      23         PyObject *exc_type;
      24         PyObject *exc_value;
      25         PyObject *exc_traceback;
      26 
      27         PyObject *dict;  /* Stores per-thread state */
      28         int gilstate_counter;
      29 
      30         ... 
      31     } PyThreadState;
      
      05 Module
    • 9. Vòng đánh giá,
       1     typedef struct _ts {
       2         struct _ts *prev;
       3         struct _ts *next;
       4         PyInterpreterState *interp;
       5 
       6         struct _frame *frame;
       7         int recursion_depth;
       8         char overflowed; 
       9                         
      10         char recursion_critical; 
      11         int tracing;
      12         int use_tracing;
      13 
      14         Py_tracefunc c_profilefunc;
      15         Py_tracefunc c_tracefunc;
      16         PyObject *c_profileobj;
      17         PyObject *c_traceobj;
      18 
      19         PyObject *curexc_type;
      20         PyObject *curexc_value;
      21         PyObject *curexc_traceback;
      22 
      23         PyObject *exc_type;
      24         PyObject *exc_value;
      25         PyObject *exc_traceback;
      26 
      27         PyObject *dict;  /* Stores per-thread state */
      28         int gilstate_counter;
      29 
      30         ... 
      31     } PyThreadState;
      
      06
      The evaluation loop,
       1     typedef struct _ts {
       2         struct _ts *prev;
       3         struct _ts *next;
       4         PyInterpreterState *interp;
       5 
       6         struct _frame *frame;
       7         int recursion_depth;
       8         char overflowed; 
       9                         
      10         char recursion_critical; 
      11         int tracing;
      12         int use_tracing;
      13 
      14         Py_tracefunc c_profilefunc;
      15         Py_tracefunc c_tracefunc;
      16         PyObject *c_profileobj;
      17         PyObject *c_traceobj;
      18 
      19         PyObject *curexc_type;
      20         PyObject *curexc_value;
      21         PyObject *curexc_traceback;
      22 
      23         PyObject *exc_type;
      24         PyObject *exc_value;
      25         PyObject *exc_traceback;
      26 
      27         PyObject *dict;  /* Stores per-thread state */
      28         int gilstate_counter;
      29 
      30         ... 
      31     } PyThreadState;
      
      06
      • 9.1 Đặt tên vào vị tríPutting names in place
      • 9.2 Các bộ phận của máyThe parts of the machine
      • 9.3 Vòng đánh giáThe Evaluation loop
      • 9.4 Một mẫu OpcodesA sampling of opcodes
    • 10. ngăn xếp khốiThe Block Stack
      • 10.1 Một ghi chú ngắn về xử lý ngoại lệA Short Note on Exception Handling
    • 11. Từ mã lớp đến mã byteFrom Class code to bytecode
    • 12. Máy phát điện: Đằng sau hậu trường.Generators: Behind the scenes.
      • 12.1 Đối tượng Trình tạoThe Generator object
      • 12.2 Chạy máy phát điệnRunning a generator
    • Ghi chú

1. Giới thiệuIntroduction

2. Quan điểm từ 30.000ft

3. Biên soạn mã nguồn Python

3.1 Từ nguồn này sang cây khác

  1. 3.2 Mã thông báo Python
  2. 3.3 Từ cây phân tích đến cây cú pháp trừu tượng
  3. 3.4 Xây dựng bảng biểu tượng

3.5 Từ AST đến mã đối tượng

4. Đối tượng Python

Công việc này là phiên bản mở rộng của các ghi chú cá nhân được thực hiện trong khi điều tra hoạt động bên trong của phiên dịch viên Python. Có một số lượng đáng kể sự khôn ngoan trong các video có sẵn trong các video PYCON, bài giảng của trường và viết blog. Công việc này sẽ không đầy đủ mà không cần thừa nhận những nguồn tuyệt vời này.

Khi kết thúc bài viết này, một người đọc nên hiểu các quy trình và cấu trúc dữ liệu rất quan trọng đối với việc thực hiện chương trình Python. Chúng tôi bắt đầu tiếp theo với một cái nhìn tổng quan về việc thực thi tập lệnh được truyền dưới dạng đối số dòng lệnh cho trình thông dịch. Người đọc có thể cài đặt

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
07 thực thi từ nguồn bằng cách làm theo các hướng dẫn tại hướng dẫn của nhà phát triển Python.

2. Quan điểm từ 30.000ftThe View From 30,000ft

Chương này là một tổng quan cấp cao về các quy trình liên quan đến việc thực hiện chương trình Python. Bất kể sự phức tạp của chương trình Python, các kỹ thuật được mô tả ở đây là như nhau. Trong các chương tiếp theo, chúng tôi phóng to để cung cấp chi tiết về các phần khác nhau của câu đố. Giải thích tuyệt vời về quá trình này được cung cấp bởi Yaniv Aknin trong loạt bài nội bộ Python của ông cung cấp một số cơ sở và động lực cho cuộc thảo luận này.

Một phương pháp thực thi tập lệnh Python là truyền nó như một đối số cho trình thông dịch Python như vậy

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
11. Có nhiều cách khác để tương tác với trình thông dịch - chúng tôi có thể bắt đầu trình thông dịch tương tác, thực thi một chuỗi dưới dạng mã, v.v. Tuy nhiên, các phương pháp này không được chúng tôi quan tâm. Hình 2.1 là luồng hoạt động liên quan đến việc thực hiện một mô-đun được chuyển cho trình thông dịch tại dòng lệnh.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 2.1: Dòng chảy trong quá trình thực thi mã nguồn

Python thực thi là một chương trình

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 như bất kỳ chương trình
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 nào khác như hạt nhân Linux hoặc chương trình
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
14 đơn giản trong
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 rất nhiều quá trình tương tự xảy ra khi chúng tôi chạy Trình thông dịch Python có thể thực thi. Điểm nhập cảnh thực thi là phương thức
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
16 trong
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
17. Phương pháp
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
16 này xử lý khởi tạo cơ bản, chẳng hạn như phân bổ bộ nhớ, cài đặt địa phương, v.v. Sau đó, nó gọi hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
19 trong
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
20 chịu trách nhiệm cho các khởi tạo cụ thể của Python. Chúng bao gồm phân tích các đối số dòng lệnh và cài đặt cờ chương trình, các biến môi trường đọc, móc chạy, thực hiện ngẫu nhiên băm, v.v. Sau,
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
19 gọi hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
22 trong
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
23;
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
22 chịu trách nhiệm khởi tạo trình thông dịch và tất cả các đối tượng và cấu trúc dữ liệu được liên kết theo yêu cầu của thời gian chạy Python. Sau khi
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
22 hoàn thành thành công, giờ đây chúng tôi có quyền truy cập vào tất cả các đối tượng Python.

Cấu trúc dữ liệu trạng thái thông dịch và trình thông dịch là hai ví dụ về cấu trúc dữ liệu được khởi tạo bằng cuộc gọi

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
22. Một cái nhìn về các định nghĩa cấu trúc dữ liệu cho những điều này cung cấp một số bối cảnh vào các chức năng của chúng. Trình thông dịch và trạng thái luồng là các cấu trúc
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 với các con trỏ đến các trường chứa thông tin cần thiết để thực hiện một chương trình. Liệt kê 2.1 là trạng thái thông dịch
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
28 (chỉ giả sử rằng
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
28 là
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 SIGN cho một định nghĩa loại mặc dù điều này không hoàn toàn đúng).

Liệt kê 2.1: Cấu trúc dữ liệu trạng thái thông dịch

 1     typedef struct _is {
 2 
 3         struct _is *next;
 4         struct _ts *tstate_head;
 5 
 6         PyObject *modules;
 7         PyObject *modules_by_index;
 8         PyObject *sysdict;
 9         PyObject *builtins;
10         PyObject *importlib;
11 
12         PyObject *codec_search_path;
13         PyObject *codec_search_cache;
14         PyObject *codec_error_registry;
15         int codecs_initialized;
16         int fscodec_initialized;
17 
18         PyObject *builtins_copy;
19     } PyInterpreterState;

Bất cứ ai đã sử dụng ngôn ngữ lập trình Python đủ lâu đều có thể nhận ra một vài lĩnh vực được đề cập trong cấu trúc này (Sysdict, Constructions, Codec)*.

  1. Trường
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    31 là một tham chiếu đến một phiên bản phiên dịch khác vì nhiều phiên dịch viên Python có thể tồn tại trong cùng một quy trình.
  2. Trường
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    32 trỏ đến luồng thực thi chính - nếu chương trình Python được đa luồng, thì trình thông dịch được chia sẻ bởi tất cả các luồng được tạo bởi chương trình - chúng tôi sẽ thảo luận về cấu trúc của trạng thái luồng sớm.
  3.  1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    33,
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    34,
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    35,
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    36 và
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    37 là tự giải thích - tất cả đều được định nghĩa là các trường hợp của
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    38 là loại gốc của tất cả các đối tượng Python trong thế giới máy ảo. Chúng tôi cung cấp thêm chi tiết về các đối tượng Python trong các chương sẽ theo sau.
  4. Các trường liên quan
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    39 giữ thông tin giúp định vị và tải mã hóa. Đây là những điều rất quan trọng để giải mã byte.

Một chương trình Python phải thực thi trong một luồng. Cấu trúc trạng thái luồng chứa tất cả các thông tin cần thiết bởi một luồng để chạy một số mã. Liệt kê 2.2 là một đoạn của cấu trúc dữ liệu luồng.

Liệt kê 2.2: Một mặt cắt của cấu trúc dữ liệu trạng thái luồng

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;

Thông tin chi tiết về trình thông dịch và cấu trúc dữ liệu trạng thái luồng sẽ theo sau trong các chương tiếp theo. Quá trình khởi tạo cũng thiết lập các cơ chế nhập khẩu cũng như stdio thô sơ.

Sau khi khởi tạo, hàm

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
19 gọi hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
41 cũng trong mô -đun
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
42. Một loạt các cuộc gọi chức năng sau:
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
43 được thực hiện cho hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
44. Cuộc gọi chức năng
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
45 tạo ra không gian tên
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
46 trong đó nội dung tệp sẽ được thực thi. Nó cũng kiểm tra sự hiện diện của phiên bản
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
47 của mô -đun - tệp
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
47 chứa phiên bản biên dịch của mô -đun thực thi. Nếu phiên bản
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
47 tồn tại, nó sẽ cố gắng đọc và thực hiện nó. Mặt khác, trình thông dịch gọi hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
50 theo sau là một cuộc gọi đến hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
44 và sau đó là hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
52. Hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
52 đọc nội dung mô -đun và xây dựng một cây phân tích từ nó. Hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
54 sau đó được gọi với cây phân tích như một đối số và tạo ra một cây cú pháp trừu tượng (AST) từ cây phân tích.

AST được tạo ra sau đó được truyền đến hàm

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
55. Hàm này gọi hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
56 tạo ra các đối tượng mã từ AST. Xin lưu ý rằng mã byte được tạo trong cuộc gọi đến
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
56 được chuyển qua trình tối ưu hóa
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
58 đơn giản để thực hiện tối ưu hóa treo thấp của mã byte được tạo trước khi tạo đối tượng mã. Với các đối tượng mã được tạo, đã đến lúc thực hiện các hướng dẫn được gói gọn bởi các đối tượng mã. Hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
55 gọi
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
60 từ
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
61 với đối tượng mã làm đối số. Điều này dẫn đến một loạt các cuộc gọi chức năng khác:
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
62. Đối tượng mã là một đối số cho hầu hết các chức năng này.
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
63 là vòng thực hiện thực tế xử lý thực thi các đối tượng mã. Hàm này được gọi với một đối tượng khung như một đối số. Đối tượng khung này cung cấp bối cảnh để thực thi đối tượng mã. Vòng thực thi đọc và thực hiện các hướng dẫn từ một mảng các hướng dẫn, thêm hoặc xóa các đối tượng khỏi ngăn xếp giá trị trong quy trình (giá trị này ở đâu?), Cho đến khi không còn hướng dẫn nào để thực hiện hoặc một cái gì đó đặc biệt phá vỡ vòng lặp này xảy ra.

Python cung cấp một tập hợp các chức năng mà người ta có thể sử dụng để khám phá các đối tượng mã thực tế. Ví dụ, một chương trình đơn giản có thể được biên dịch thành một đối tượng mã và được tháo rời để có được các opcodes được thực thi bởi máy ảo Python, như trong Liệt kê 2.3.

Liệt kê 2.3: Tháo chức năng Python

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        

Tệp

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
64 chứa một danh sách các hướng dẫn mã Byte của máy ảo Python. Các opcodes khá thẳng về mặt khái niệm. Lấy ví dụ của chúng tôi từ Liệt kê 2.3 với bốn hướng dẫn - Opcode Load_Fast tải giá trị của đối số của nó (
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
65 trong trường hợp này) vào ngăn xếp đánh giá (giá trị). Máy ảo Python là một máy ảo dựa trên ngăn xếp, vì vậy các giá trị cho các hoạt động và kết quả từ các hoạt động trực tiếp trên một ngăn xếp. Opcode
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
66 sau đó bật hai mục từ ngăn xếp giá trị, thực hiện phép nhân nhị phân trên cả hai giá trị và đặt kết quả trở lại vào ngăn xếp giá trị. Opcode
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
67 bật một giá trị từ ngăn xếp, đặt đối tượng giá trị trả về cho giá trị này và thoát ra khỏi vòng thông dịch. Từ việc tháo gỡ trong Danh sách 2.3, một điều khá rõ ràng là lời giải thích khá đơn giản này về hoạt động của vòng lặp phiên dịch để loại bỏ rất nhiều chi tiết. Một vài trong số những câu hỏi nổi bật này có thể bao gồm.

Sau khi thực hiện mô-đun, chức năng

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
19 tiếp tục với quy trình dọn dẹp. Giống như
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
22 thực hiện khởi tạo trong quá trình khởi động phiên dịch,
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
70 được gọi để thực hiện một số công việc dọn dẹp; Quá trình dọn dẹp này liên quan đến việc chờ đợi các luồng thoát ra, gọi bất kỳ móc thoát nào, giải phóng bất kỳ bộ nhớ nào được phân bổ bởi trình thông dịch vẫn đang được sử dụng, v.v., mở đường cho thông dịch viên thoát ra.

Trên đây là một tổng quan cấp cao về các quy trình liên quan đến việc thực hiện mô-đun Python. Rất nhiều chi tiết bị bỏ lại ở giai đoạn này, nhưng tất cả sẽ được tiết lộ trong các chương tiếp theo. Chúng tôi tiếp tục trong chương tiếp theo với một mô tả về quy trình biên dịch.

3. Biên soạn mã nguồn PythonCompiling Python Source Code

Mặc dù hầu hết mọi người có thể không coi Python là ngôn ngữ được biên dịch, nhưng nó là một. Trong quá trình biên dịch, trình thông dịch tạo mã byte có thể thực thi từ mã nguồn Python. Tuy nhiên, quy trình biên dịch Python sườn là một quy trình tương đối đơn giản. Nó liên quan đến các bước sau đây theo thứ tự.

  1. Phân tích mã nguồn vào một cây phân tích.
  2. Biến đổi cây phân tích thành cây cú pháp trừu tượng (AST).
  3. Tạo bảng ký hiệu.
  4. Tạo đối tượng mã từ AST. Bước này liên quan đến:
    1. Biến AST thành biểu đồ điều khiển dòng chảy và
    2. Phát ra một đối tượng mã từ biểu đồ luồng điều khiển.

Mã nguồn phân tích mã nguồn vào cây phân tích và tạo AST từ một phân tích như vậy là một quá trình tiêu chuẩn và Python không đưa bất kỳ sắc thái phức tạp nào, vì vậy trọng tâm của chương này là chuyển đổi AST thành biểu đồ luồng điều khiển và phát xạ của Đối tượng mã từ biểu đồ luồng điều khiển. Đối với bất kỳ ai quan tâm đến Parse Tree và AST Generation, The Dragon Book cung cấp một tour du lịch chuyên sâu của cả hai chủ đề.

3.1 Từ nguồn này sang cây khácFrom Source To Parse Tree

Trình phân tích cú pháp Python là trình phân tích cú pháp LL (1) dựa trên mô tả của các trình phân tích cú pháp như vậy trong cuốn sách rồng. Mô-đun

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
71 chứa đặc điểm ngữ pháp của biểu mẫu Backus-Naur (EBNF) mở rộng của ngôn ngữ Python. Danh sách 3.0 là một mặt cắt ngang của ngữ pháp này.

Liệt kê 3.0: Một phần chéo của ngữ pháp Python BNF

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...

Hàm

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
52 trong
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
73 là điểm nhập để phân tích bất kỳ mô-đun nào được truyền cho trình thông dịch tại dòng lệnh. Hàm này gọi hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
74 chịu trách nhiệm tạo mã thông báo từ các mô -đun được cung cấp.

3.2 Mã thông báo PythonPython tokens

Mã nguồn Python bao gồm các mã thông báo. Ví dụ:

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
75 là mã thông báo từ khóa;
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
76 là mã thông báo số theo nghĩa đen. Mã thông báo, phân tách mã nguồn thành mã thông báo cấu thành, là nhiệm vụ đầu tiên trong quá trình phân tích cú pháp. Các mã thông báo từ bước này rơi vào các loại sau.

  1. Định danh: Đây là những tên được xác định bởi một lập trình viên. Chúng bao gồm tên chức năng, tên biến, tên lớp, v.v ... Chúng phải phù hợp với các quy tắc của các định danh được chỉ định trong tài liệu Python.
  2. Các nhà khai thác: Đây là các biểu tượng đặc biệt như
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    77,
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    78 hoạt động trên các giá trị dữ liệu và tạo ra kết quả.
  3. DELIMITERS: Nhóm các biểu tượng này phục vụ cho các biểu thức nhóm, cung cấp dấu chấm câu và bài tập. Ví dụ trong danh mục này bao gồm
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    79,
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    80,
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    81,
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    82, v.v.
  4. Biết chữ: Đây là những biểu tượng cung cấp giá trị không đổi cho một số loại. Chúng tôi có chuỗi và chữ byte như
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    83,
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    84 và các chữ số bao gồm các chữ số nguyên như
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    76, theo nghĩa đen của điểm nổi như
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    86 và các văn bản tưởng tượng như
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    87.
  5. Nhận xét: Đây là những chữ viết bắt đầu với biểu tượng băm. Mã thông báo nhận xét luôn kết thúc ở cuối dòng vật lý.
  6. NEWLINE: Đây là một mã thông báo duy nhất biểu thị kết thúc của một dòng logic.
  7. Thắng và dành: Những mã thông báo này đại diện cho các cấp độ thụt vào các câu lệnh ghép nhóm.

Một nhóm các mã thông báo được phân định bởi mã thông báo mới tạo nên một dòng logic; Do đó, chúng tôi có thể nói rằng một chương trình Python bao gồm một chuỗi các dòng logic. Mỗi dòng logic này bao gồm một số dòng vật lý được kết thúc bởi một chuỗi cuối dòng. Hầu hết các lần, các dòng logic đều bản đồ đến các dòng vật lý, vì vậy chúng tôi có một dòng logic được phân định bởi các ký tự cuối dòng. Những dòng logic này thường ánh xạ tới các câu lệnh Python. Báo cáo ghép có thể trải rộng nhiều dòng vật lý; ngoặc đơn, dấu ngoặc vuông hoặc niềng răng xoăn xung quanh một tuyên bố ngầm tham gia các dòng logic tạo nên tuyên bố như vậy. Mặt khác, ký tự dấu gạch chéo ngược là cần thiết để tham gia nhiều dòng logic một cách rõ ràng.NEWLINE token makes up a logical line; hence we could say that a Python program consists of a sequence of logical lines. Each of these logical lines consists of several physical lines that are each terminated by an end-of-line sequence. Most times, logical lines map to physical lines, so we have a logical line delimited by end-of-line characters. These logical lines usually map to Python statements. Compound statements may span multiple physical lines; parenthesis, square brackets or curly braces around a statement implicitly joins the logical lines that make up such statement. The backslash character, on the other hand, is needed to join multiple logical lines explicitly.

Th thụt lề cũng đóng một vai trò trung tâm trong việc nhóm các tuyên bố Python. Do đó, một trong những dòng trong ngữ pháp Python là

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
88 vì vậy một nhiệm vụ quan trọng của tokenizer tạo ra các mã thông báo
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
89 và
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
90 đi vào cây phân tích. Tokenizer sử dụng một thuật toán tương tự như trong danh sách 3.1 để tạo các mã thông báo
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
91 và
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
92 này.

Liệt kê 3.1: Thuật toán thụt python

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.

Hàm

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
74 trong
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
94 quét tệp nguồn từ trái sang phải và từ trên xuống dưới mã thông báo nội dung tệp và sau đó xuất ra cấu trúc
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
95. Các ký tự không gian trắng khác ngoài Kẻ hủy diệt phục vụ để phân định mã thông báo nhưng không bắt buộc. Trong các trường hợp mơ hồ như trong
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
96, một mã thông báo bao gồm chuỗi dài nhất có thể tạo thành một mã thông báo hợp pháp từ trái sang phải; Trong ví dụ này, các mã thông báo là nghĩa đen
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
76, toán tử
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
77 và nghĩa đen
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
76.

Cấu trúc tokenizer được tạo bởi hàm

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
74 được chuyển đến hàm
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
01 cố gắng xây dựng một cây phân tích theo ngữ pháp Python trong đó liệt kê 3.0 là một tập hợp con. Khi trình phân tích cú pháp gặp phải một mã thông báo vi phạm ngữ pháp Python, nó sẽ tăng ngoại lệ
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
02. Mô -đun
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
03 cung cấp quyền truy cập hạn chế vào cây phân tích của một khối mã Python và liệt kê 3.2 là một trình diễn cơ bản.

Liệt kê 3.2: Sử dụng mô -đun phân tích cú pháp để lấy cây phân tích của mã Python

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  

Cuộc gọi

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
04 trong Liệt kê 3.2 Trả về một biểu diễn trung gian của một cây phân tích
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
05 trong khi cuộc gọi đến
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
06 trả về cây phân tích được biểu thị bằng danh sách Python - mỗi danh sách đại diện cho một nút của cây Parse. Các mục đầu tiên trong mỗi danh sách, số nguyên, xác định quy tắc sản xuất trong ngữ pháp Python chịu trách nhiệm cho nút đó.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 3.0: Một cây phân tích để liệt kê 3.2 (một hàm trả về chuỗi ‘Xin chào thế giới)

Hình 3.0 là một sơ đồ cây của cùng một cây phân tích từ Liệt kê 3.2 với một số mã thông báo bị tước đi, và người ta có thể dễ dàng thấy phần ngữ pháp dễ dàng hơn của từng giá trị số nguyên. Các quy tắc sản xuất này đều được chỉ định trong các tệp tiêu đề

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
07 (thiết bị đầu cuối) và
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
08 (thiết bị đầu cuối).

3.3 Từ cây phân tích đến cây cú pháp trừu tượngFrom Parse Tree To Abstract Syntax Tree

Cây Parse dày đặc với thông tin về cú pháp Python, và tất cả các thông tin đó như cách các dòng được phân định là không liên quan để tạo mã byte. Đây là nơi cây cú pháp trừu tượng (AST) xuất hiện. Cây cú pháp trừu tượng là một đại diện của mã độc lập với các kết quả của cú pháp Python. Ví dụ, một cây phân tích chứa các cấu trúc cú pháp như các nút đại tràng và newline, như trong Hình 3.0, nhưng AST không bao gồm cấu trúc cú pháp như trong danh sách 3.4. Việc chuyển đổi cây phân tích thành cây cú pháp trừu tượng là bước tiếp theo trong đường ống biên dịch.

Liệt kê 3.4: Sử dụng mô -đun
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
09 để thao tác với AST của mã nguồn Python

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')

Python sử dụng ngôn ngữ định nghĩa cú pháp Tóm tắt Zephyr (ASDL) và các định nghĩa ASDL của các cấu trúc Python khác nhau có trong tệp

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
10 tệp. Liệt kê 3.5 là một đoạn của định nghĩa ASDL của câu lệnh Python.

Liệt kê 3.5: Một đoạn định nghĩa ASDL của câu lệnh Python

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)

Hàm

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
11 trong
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
12 gọi
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
13 cũng trong
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
12 hướng dẫn các nút cây phân tích khác nhau và tạo các nút AST phù hợp bằng cách sử dụng các hàm được xác định trong
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
12. Trái tim của hàm này là một câu lệnh chuyển đổi lớn gọi các hàm cụ thể của nút trên mỗi loại nút. Ví dụ: mã chịu trách nhiệm tạo nút
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
16 cho biểu thức
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17 nằm trong danh sách 3.7.

Liệt kê 3.7: Chức năng tạo nút AST cho biểu thức IF

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }

Liệt kê 3.8: Chức năng Python đơn giản

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)

Lấy mã trong Liệt kê 3.8, ví dụ, việc chuyển đổi cây phân tích cú pháp của nó thành AST sẽ dẫn đến AST tương tự như Hình 3.1.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 3.1: AST để liệt kê 3.2

Mô -đun

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
09 đi kèm với trình thông dịch Python cung cấp cho chúng tôi khả năng thao tác với Python AST. Các công cụ như
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
19 có thể lấy biểu diễn
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
16 trong Python và xuất mã nguồn Python tương ứng.

Với AST được tạo, bước tiếp theo là tạo bảng ký hiệu.

3.4 Xây dựng bảng biểu tượngBuilding The Symbol Table

Bảng ký hiệu, như tên cho thấy, là một tập hợp các biểu tượng và bối cảnh sử dụng của chúng trong một khối mã. Xây dựng bảng biểu tượng liên quan đến việc phân tích và gán phạm vi cho các tên trong một khối mã.

Hàm

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
21 trong
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
22 đi bộ AST để tạo bảng ký hiệu. Đây là một quá trình hai bước được tóm tắt trong danh sách 3.12.

Liệt kê 3.12: Tạo bảng ký hiệu từ AST

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
0

Đầu tiên, chúng tôi truy cập từng nút của

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
16 để xây dựng một bộ sưu tập các biểu tượng được sử dụng. Sau lần vượt qua đầu tiên, các mục bảng ký hiệu chứa tất cả các tên đã được sử dụng trong mô -đun, nhưng nó không có thông tin theo ngữ cảnh về các tên đó. Ví dụ, trình thông dịch không thể biết nếu một biến nhất định là biến toàn cầu, cục bộ hoặc miễn phí. Hàm
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
24 trong
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
25 xử lý giai đoạn thứ hai. Trong giai đoạn này, thuật toán gán phạm vi (cục bộ, toàn cầu hoặc miễn phí) cho các biểu tượng được thu thập từ đường chuyền đầu tiên. Các ý kiến ​​trong
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
25 khá nhiều thông tin và được diễn giải bên dưới để cung cấp một số hiểu biết sâu sắc về giai đoạn thứ hai của quy trình xây dựng bảng biểu tượng.

Bảng ký hiệu yêu cầu hai lần vượt qua để xác định phạm vi của mỗi tên. Đường chuyền đầu tiên thu thập các sự kiện thô từ AST thông qua các hàm symtable_visit_* trong khi vượt qua thứ hai phân tích các sự kiện này trong quá trình vượt qua pystentryobject được tạo ra trong PASS 1. Trong lần thứ hai Khi nó vào một chức năng. Các ràng buộc này xác định xem các biến không phải là tự do là miễn phí hay toàn cầu ẩn. Các tên được khai báo rõ ràng không phải là không có trong tập hợp các tên có thể nhìn thấy này - nếu chúng không, trình thông dịch sẽ gây ra lỗi cú pháp. Sau khi phân tích cục bộ, nó phân tích từng khối con của nó bằng cách sử dụng một bộ ràng buộc tên được cập nhật.

Ngoài ra còn có hai loại biến toàn cầu, ngầm và rõ ràng. Một toàn cầu rõ ràng được tuyên bố với tuyên bố toàn cầu. Một toàn cầu ngầm là một biến miễn phí mà trình biên dịch đã không tìm thấy ràng buộc trong phạm vi hàm kèm theo. Toàn cầu ngầm là toàn cầu hoặc xây dựng. Mô -đun và khối lớp Python sử dụng các opcodes

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
27 để xử lý các tên này để thực hiện ngữ nghĩa hơi kỳ lạ. Trong một khối như vậy, tên được coi là toàn cầu cho đến khi nó được gán một giá trị; Sau đó, nó được đối xử như một địa phương.
Python’s module and class blocks use the
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
27 opcodes to handle these names to implement slightly odd semantics. In such a block, the name is treated as global until it is assigned a value; then it is treated like a local.

Trẻ em cập nhật bộ biến miễn phí. Nếu một đứa trẻ thêm một biến vào tập hợp các biến miễn phí, thì biến đó được đánh dấu là một ô. Đối tượng chức năng được xác định phải cung cấp lưu trữ thời gian chạy cho biến có thể vượt qua khung chức năng. Các biến ô được xóa khỏi tập miễn phí trước khi hàm phân tích trở về cha mẹ của nó.

Ví dụ: bảng ký hiệu cho một mô -đun có nội dung trong danh sách 3.16 sẽ chứa ba mục bảng biểu tượng.

Liệt kê 3.16: một chức năng đơn giản

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
1

Mục đầu tiên là của mô -đun kèm theo và nó sẽ có

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
28 được xác định với phạm vi cục bộ. Mục nhập bảng biểu tượng tiếp theo sẽ là chức năng
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
28 và điều này sẽ có các tên
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
30 và
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
31 được đánh dấu là cục bộ. Mục nhập bảng ký hiệu cuối cùng sẽ là chức năng
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
31 lồng nhau. Mục nhập này sẽ có biến số được đánh dấu là
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
33. Một điều cần lưu ý là mặc dù
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
28 có phạm vi cục bộ trong mục nhập bảng ký hiệu cho khối mô -đun, nhưng nó được xác định toàn cầu trong khối mã mô -đun vì trường
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
35 của bảng biểu tượng trỏ đến mục biểu tượng
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
36 các mô -đun kèm theo.

3.5 Từ AST đến mã đối tượngFrom AST To Code Objects

Sau khi tạo bảng ký hiệu, bước tiếp theo là tạo các đối tượng mã. Các chức năng cho bước này nằm trong mô -đun

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
22. Đầu tiên, họ chuyển đổi
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
16 thành các khối cơ bản của các hướng dẫn mã byte python. Các khối cơ bản là các khối mã có một mục nhập duy nhất nhưng có thể có nhiều lối ra. Thuật toán ở đây sử dụng một mẫu tương tự như được sử dụng để tạo bảng ký hiệu. Các hàm có tên
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
39, trong đó
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
40 là loại nút, truy cập đệ quy từng nút của AST phát ra các hướng dẫn mã byte trong quá trình. Chúng tôi thấy một số ví dụ về các chức năng này trong các phần tiếp theo. Các khối của mã byte ở đây hoàn toàn biểu thị một biểu đồ, biểu đồ luồng điều khiển. Biểu đồ này hiển thị các đường dẫn thực thi mã tiềm năng. Trong bước thứ hai, thuật toán làm phẳng biểu đồ luồng điều khiển bằng cách sử dụng độ sâu tìm kiếm đầu tiên theo thứ tự. Sau đó, các lần bù nhảy được tính toán và sử dụng làm đối số hướng dẫn cho các hướng dẫn bytecode
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
41. Các hướng dẫn bytecode sau đó được sử dụng để tạo một đối tượng mã.

Các khối cơ bản

Khối cơ bản là trung tâm để tạo các đối tượng mã. Một khối cơ bản là một chuỗi các hướng dẫn có một điểm nhập nhưng nhiều điểm thoát. Liệt kê 3.19 là định nghĩa của cấu trúc dữ liệu

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
42.

Liệt kê 3.19: Dữ liệu
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
43

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
2

Các trường thú vị ở đây là

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
44 là danh sách được liên kết của tất cả các khối cơ bản được phân bổ trong quá trình biên dịch,
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
45 là một loạt các hướng dẫn trong khối cơ bản và
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
46 là luồng cơ bản tiếp theo đạt được bằng cách thực hiện luồng điều khiển thông thường. Mỗi hướng dẫn có một cấu trúc được hiển thị trong danh sách 3.20 giữ một lệnh bytecode. Các hướng dẫn bytecode này nằm trong tệp tiêu đề
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
47.

Liệt kê 3.20: Dữ liệu
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
48

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
3

Để minh họa cách trình thông dịch tạo các khối cơ bản này, chúng tôi sử dụng hàm trong Liệt kê 3.11. Việc biên dịch AST của nó được hiển thị trong Hình 3.2 thành CFG dẫn đến biểu đồ tương tự như trong Hình 3.4 - điều này chỉ hiển thị các khối với các hướng dẫn. Việc kiểm tra biểu đồ này cung cấp một số trực giác đằng sau các khối cơ bản. Một số khối cơ bản có một điểm nhập duy nhất, nhưng một số khác có nhiều lối ra. Các khối này được mô tả chi tiết hơn tiếp theo.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 3.4: Biểu đồ luồng điều khiển cho hàm FizzBuzz trong Liệt kê 3.11.

Liệt kê 3.21: Biên soạn câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
4

Phần thân của chức năng trong danh sách 3.13 là một câu lệnh

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17 như có thể nhìn thấy trong Hình 3.2. Đoạn trích trong danh sách 3.21 là hàm biên dịch câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
16 vào các khối cơ bản. Khi hàm này biên dịch nút câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17 của chúng tôi, câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
54 trên dòng 20 được thực thi. Đầu tiên, nó tạo ra một khối cơ bản mới cho một nút
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
54 nếu như vậy tồn tại. Sau đó, nó truy cập vào mệnh đề bảo vệ của nút câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17. Những gì chúng ta có trong chức năng trong danh sách 3.11 rất thú vị vì mệnh đề Guard là một biểu thức boolean có thể kích hoạt một bước nhảy trong khi thực hiện. Liệt kê 3.22 là hàm biên dịch biểu thức boolean.

Liệt kê 3.22: Biên soạn một tuyên bố Boolean

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
5

Mã lên đến vòng lặp ở dòng 20 là thẳng về phía trước. Trong vòng lặp, trình biên dịch truy cập từng biểu thức và sau mỗi lần truy cập, nó thêm một

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
41. Điều này là do đánh giá ngắn mạch được sử dụng bởi Python. Điều đó có nghĩa là khi một hoạt động boolean như
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
58 đánh giá thành
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
59, trình thông dịch bỏ qua các biểu thức khác và thực hiện một bước nhảy để tiếp tục thực hiện. Trình biên dịch biết nơi cần nhảy đến nếu cần vì các hướng dẫn sau đi vào một khối cơ bản mới - việc sử dụng
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
60 thực thi điều này. Vì vậy, chúng tôi có hai khối bây giờ. Sau khi truy cập thử nghiệm, hàm
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
61 sẽ thêm lệnh nhảy cho câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17, sau đó biên dịch phần thân của câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17. Hãy nhớ lại rằng sau khi truy cập biểu thức Boolean, trình biên dịch đã tạo ra một khối cơ bản mới. Khối này chứa các bước nhảy và hướng dẫn cho phần thân của câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17, một lợi nhuận đơn giản trong trường hợp này. Mục tiêu của bước nhảy này là khối tiếp theo sẽ nắm giữ nhánh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
65 của câu lệnh IF. Bước tiếp theo là biên dịch thành phần
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
65 của câu lệnh IF nhưng trước đó, trình biên dịch gọi hàm
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
60 để kích hoạt khối
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
68. Cánh tay
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
69 chỉ là một tuyên bố
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17 khác, do đó hàm
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
61 được gọi lại. Lần này trong suốt bài kiểm tra của
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17 là một hoạt động so sánh. Đây là một so sánh duy nhất, do đó không có bước nhảy nào liên quan và không có khối mới, do đó, trình thông dịch phát ra mã byte để so sánh các giá trị và trả về để biên dịch phần thân của câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
17. Quá trình tương tự tiếp tục cho cánh tay
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
69 cuối cùng dẫn đến CFG trong Hình 3.3.

Hình 3.3 cho thấy hàm

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
75 có thể thoát khỏi khối 1 theo hai cách. Đầu tiên là thông qua thực hiện nối tiếp tất cả các hướng dẫn trong Khối 1 sau đó tiếp tục trong khối 2. Cái còn lại thông qua lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
41 sau thao tác so sánh đầu tiên. Mục tiêu của bước nhảy này là khối 3, nhưng một đối tượng mã thực thi không biết gì về các khối cơ bản - đối tượng mã có một luồng byte được lập chỉ mục với độ lệch. Chúng tôi phải cung cấp các hướng dẫn nhảy với độ lệch vào luồng lệnh bytecode của các mục tiêu nhảy.

Lắp ráp các khối cơ bản

Hàm

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
77 trong
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
22 tuyến tính hóa CFG và tạo đối tượng mã từ CFG tuyến tính hóa. Nó làm như vậy bằng cách tính toán các phần bù hướng dẫn cho các mục tiêu nhảy và sử dụng các mục tiêu này làm đối số cho các hướng dẫn nhảy.

Đầu tiên, chức năng lắp ráp, trong trường hợp này, thêm các hướng dẫn cho câu lệnh

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
79 Vì câu lệnh cuối cùng của hàm không phải là câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
80 - bây giờ bạn biết lý do tại sao bạn có thể xác định các phương thức mà không cần thêm câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
80. Tiếp theo, nó làm hỏng CFG bằng cách sử dụng một lần đi ngang trước theo thứ tự-Traversal sau đơn đặt hàng đến thăm trẻ em của một nút trước khi truy cập nút. Cấu trúc dữ liệu trình biên dịch giữ biểu đồ phẳng,
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
82, trong mảng
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
83 để xử lý thêm. Tiếp theo, nó tính toán các độ lệch hướng dẫn và sử dụng các mục tiêu này làm mục tiêu cho các hướng dẫn nhảy bytecode. Hàm
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
84 trong danh sách 3.24 xử lý việc này.

Hàm

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
84 trong danh sách 3.24 tương đối đơn giản. Trong
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
86 ở dòng 10, nó tính toán độ lệch vào luồng lệnh cho mọi hướng dẫn (gần giống với một chỉ mục mảng). Trong
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
86 tiếp theo ở dòng 17, nó sử dụng các độ lệch được tính toán làm đối số cho các hướng dẫn nhảy phân biệt giữa các bước nhảy tuyệt đối và tương đối.

Liệt kê 3.24: Tính toán mã bytepode

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
6

Với các hướng dẫn bù được tính toán và nhảy bù được lắp ráp, trình biên dịch phát ra các hướng dẫn có trong biểu đồ phẳng theo thứ tự sau ngược từ đường truyền. Thứ tự bài ngược là một phân loại tôpô của CFG. Điều này có nghĩa là cho mỗi cạnh từ đỉnh U đến đỉnh v, u đến trước v theo thứ tự sắp xếp. Điều này là hiển nhiên; Chúng tôi muốn một nút nhảy đến một nút khác để luôn luôn đến trước mục tiêu nhảy đó. Sau khi phát ra các hướng dẫn bytecode, trình biên dịch sẽ tạo các đối tượng mã cho mỗi khối mã bằng cách sử dụng mã byte được phát ra và thông tin có trong bảng ký hiệu. Đối tượng mã được tạo được trả về hàm gọi đánh dấu sự kết thúc của quá trình biên dịch.

4. Đối tượng PythonPython Objects

Trong chương này, chúng tôi xem xét các đối tượng Python và việc triển khai của chúng trong máy ảo Cpython. Đây là trung tâm để hiểu máy ảo Python. Hầu hết các nguồn được tham chiếu trong chương này đều có sẵn trong các thư mục

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
88 và
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
89. Không có gì đáng ngạc nhiên, việc triển khai hệ thống đối tượng Python khá phức tạp, vì vậy chúng tôi cố gắng tránh bị sa lầy trong các chi tiết đẫm máu về việc triển khai
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08. Để khởi động điều này, chúng tôi bắt đầu bằng cách nhìn vào cấu trúc
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38 - công việc của hệ thống đối tượng Python.

4.1 PyobjectPyObject

Một kiểm tra chữ thảo của mã nguồn cpython cho thấy tính phổ biến của cấu trúc

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38. Như chúng ta sẽ thấy sau này trong chuyên luận này, tất cả các đối tượng ngăn xếp giá trị được thông dịch sử dụng trong quá trình đánh giá là
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38s. Vì muốn có một thuật ngữ tốt hơn, chúng tôi gọi đây là siêu lớp của tất cả các đối tượng Python. Các giá trị không bao giờ được khai báo là
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38 nhưng một con trỏ đến bất kỳ đối tượng nào có thể được chuyển đến
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38. Trong thuật ngữ Layman, bất kỳ đối tượng nào cũng có thể được coi là cấu trúc
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38 vì phân đoạn ban đầu của tất cả các đối tượng là cấu trúc
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38.

Liệt kê 4.0 là một định nghĩa về cấu trúc

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38. Cấu trúc này bao gồm một số trường phải được lấp đầy cho một giá trị được coi là một đối tượng.

Liệt kê 4.0: Định nghĩa Pyobject

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
7

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
99 khi có mặt là macro
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 xác định các trường trỏ đến đối tượng được phân bổ trước đó và đối tượng tiếp theo, do đó tạo thành một danh sách liên kết gấp đôi của tất cả các đối tượng trực tiếp. Trường
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
01 là để quản lý bộ nhớ, trong khi
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
02 là một con trỏ đến đối tượng loại cho đối tượng đã cho. Loại này xác định những gì dữ liệu thể hiện, loại dữ liệu mà nó chứa và loại hoạt động mà đối tượng hỗ trợ. Lấy đoạn trích trong liệt kê 4.1 chẳng hạn, tên,
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
03, trỏ đến một đối tượng chuỗi và loại đối tượng là Hồi Str.

Danh sách 4.1: Tuyên bố biến trong Python

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
8

Một câu hỏi hợp lệ từ đây là nếu trường Loại trỏ đến đối tượng

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04 thì trường
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
02 của đối tượng
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04 chỉ ra là gì?
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
07 cho một đối tượng loại đề cập đến cách tự đề cập đến chính nó do đó câu nói rằng loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04 là
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04.

Các loại trong VM được triển khai bằng cấu trúc dữ liệu

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
10 được xác định trong mô -đun
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
11. Đây là một c
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
12 với các trường cho hầu hết các chức năng hoặc bộ sưu tập các chức năng được điền theo từng loại. Chúng tôi xem xét cấu trúc dữ liệu này tiếp theo.

4.2 Các loại mổ xẻDissecting Types

Cấu trúc

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
10 được xác định trong
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
14 đóng vai trò là cấu trúc cơ sở của tất cả các loại Python. Cấu trúc dữ liệu xác định một số lượng lớn các trường chủ yếu là con trỏ đến các chức năng C thực hiện một số chức năng cho một loại nhất định. Liệt kê 4.2 là định nghĩa cấu trúc
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
10.all Python types. The data structure defines a large number of fields that are mostly pointers to C functions that implement some functionality for a given type. Listing 4.2 is the
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
10 structure definition.

Liệt kê 4.2: Định nghĩa PytypeObject

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
9

Trường

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
16 là một phần mở rộng của trường
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38 được thảo luận trong phần trước; Phần mở rộng này thêm một trường
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
18 cho các đối tượng có khái niệm về độ dài. Tài liệu API Python C chứa một mô tả về từng trường trong cấu trúc đối tượng này. Điều quan trọng cần lưu ý là các trường trong cấu trúc mỗi thực hiện một phần của hành vi loại. Hầu hết các trường này là một phần của những gì chúng ta có thể gọi là giao diện hoặc giao thức đối tượng; Các loại thực hiện các chức năng này nhưng theo một cách cụ thể. Ví dụ: trường
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
19 là tham chiếu đến hàm băm cho một loại đã cho - trường này có thể được để lại mà không có giá trị trong trường hợp các trường hợp của loại không thể băm; Bất cứ hàm nào nằm trong trường
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
19 đều được gọi khi phương thức
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
21 được gọi trên một thể hiện của loại đó. Đối tượng loại cũng có trường -
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
22 tham chiếu các phương thức duy nhất cho loại đó. Khe khe
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 đề cập đến một hàm tạo ra các thể hiện mới của loại và như vậy. Một số trong các trường này, chẳng hạn như
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
24, là tùy chọn - không phải mọi loại đều cần chạy chức năng khởi tạo, đặc biệt là khi loại là bất biến, chẳng hạn như bộ dữ liệu. Ngược lại, các lĩnh vực khác, chẳng hạn như
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23, là bắt buộc.

Ngoài ra, trong số các lĩnh vực này là các trường cho các giao thức Python khác, chẳng hạn như sau.

  1. Giao thức số - Một loại thực hiện giao thức này sẽ có triển khai cho trường
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    26. Trường này là một tham chiếu đến một tập hợp các hàm thực hiện các hoạt động số học (điều này không nhất thiết phải có trên các số). Một loại sẽ hỗ trợ các hoạt động số học với các triển khai tương ứng của chúng có trong
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    27 được đặt theo cách cụ thể của loại. Ví dụ, loại
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    28 không phải là số có một mục vào lĩnh vực này vì nó hỗ trợ các hoạt động số học như
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    29,
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    30, v.v.
  2. Giao thức trình tự - Một loại thực hiện giao thức này sẽ có giá trị trong trường
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    31. Giá trị này sẽ cung cấp loại đó hỗ trợ cho một số hoạt động trình tự như
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    32,
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    33, v.v.
  3. Giao thức ánh xạ - Một loại thực hiện giao thức này sẽ có giá trị trong
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    34. Giá trị này cho phép loại đó được xử lý như từ điển Python bằng cách sử dụng cú pháp từ điển để thiết lập và truy cập các ánh xạ giá trị khóa.
  4. Giao thức Iterator - Một loại thực hiện giao thức này sẽ có giá trị trong các trường
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    35 và có thể các trường
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    36 cho phép các trường hợp của loại được sử dụng như trình lặp python.
  5. Giao thức bộ đệm - Một loại thực hiện giao thức này sẽ có giá trị trong trường
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    37. Các chức năng này sẽ cho phép truy cập vào các phiên bản của loại dưới dạng bộ đệm đầu vào/đầu ra.

Tiếp theo, chúng tôi xem một vài đối tượng loại là nghiên cứu trường hợp về cách các trường đối tượng loại được điền.

4.3 Loại nghiên cứu trường hợp đối tượngType Object Case Studies

Loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
38

Chúng tôi xem xét loại

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
38 để cảm nhận về cách các trường của một đối tượng được điền. Chúng tôi chọn điều này bởi vì nó tương đối dễ dàng để grok với kích thước nhỏ của việc triển khai - khoảng một ngàn dòng cộng của
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 bao gồm các chuỗi tài liệu. Liệt kê 4.3 cho thấy việc thực hiện loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
38.

Liệt kê 4.3: Định nghĩa loại Tuple

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
0

Chúng tôi nhìn vào các trường được điền vào loại này.

  1.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    16 đã được khởi tạo với một đối tượng loại - pytype_type là loại. Hãy nhớ lại rằng loại đối tượng loại là loại. Một cái nhìn về đối tượng loại pytype_type cho thấy loại pytype_type là chính nó.
  2.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    43 được khởi tạo thành tên của loại - tuple.
  3.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    44 và
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    45 đề cập đến kích thước của đối tượng tuple và các mục có trong đối tượng tuple, và điều này được điền vào tương ứng.
  4.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    46 là một chức năng quản lý bộ nhớ xử lý việc giải quyết bộ nhớ khi một đối tượng tuple bị phá hủy.
  5.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    47 là hàm được gọi khi hàm
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    48 được gọi với một thể hiện tuple làm đối số.
  6.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    49 là tập hợp các phương thức trình tự mà Tuple thực hiện. Hãy nhớ lại rằng một hỗ trợ tuple
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    33,
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    32, v.v.
  7.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    52 là tập hợp các phương thức ánh xạ được hỗ trợ bởi một tuple - trong trường hợp này, các khóa chỉ là các chỉ mục số nguyên.
  8.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    53 là chức năng được gọi bất cứ khi nào băm của đối tượng tuple được yêu cầu. Điều này xuất hiện khi các bộ đếm được sử dụng làm phím từ điển hoặc trong các bộ.
  9.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    54 là hàm chung được gọi khi tham chiếu các thuộc tính của đối tượng tuple. Chúng tôi xem xét tham chiếu thuộc tính trong các phần tiếp theo.
  10.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    55 là chuỗi tài liệu cho một đối tượng tuple.
  11.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    56 là chức năng truyền tải cho bộ sưu tập rác của một đối tượng tuple. Chức năng này được sử dụng bởi bộ thu rác để giúp phát hiện chu kỳ tham chiếu1.
  12.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    57 là một phương pháp được gọi khi hàm
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    58 được gọi trên một đối tượng tuple. Trong trường hợp này, một loại
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    59 hoàn toàn khác được trả về để không có triển khai cho phương thức
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    60.
  13.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    61 là các phương pháp thực tế của một loại tuple.
  14.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    62 là hàm được gọi để tạo các phiên bản mới của loại tuple.
  15.  1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    63 là một lĩnh vực khác tham chiếu chức năng quản lý bộ nhớ.

Các trường bổ sung với các giá trị

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
64 trống vì các bộ dữ liệu không yêu cầu các chức năng đó. Lấy trường
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
24, ví dụ, một tuple là một loại bất biến, do đó, một khi được tạo ra, nó không thể thay đổi, do đó không cần phải khởi tạo nào ngoài những gì xảy ra trong hàm được tham chiếu bởi
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23; Do đó trường này bị bỏ trống.

Loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04

Loại khác chúng tôi xem xét là loại

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04. Đây là metatype cho tất cả các loại tích hợp và các loại do người dùng xác định Vanilla (người dùng có thể xác định một siêu dữ liệu mới)-Lưu ý cách loại này được sử dụng khi khởi tạo đối tượng
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
38 trong
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
70. Khi thảo luận về các loại, điều cần thiết là phân biệt giữa các đối tượng có
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04 là loại và đối tượng của chúng với loại do người dùng xác định. Sự khác biệt này đến rất nhiều trước khi xử lý tham chiếu thuộc tính trong các đối tượng.

Loại này xác định các phương thức được sử dụng khi làm việc với các loại khác và các trường tương tự như các phương thức từ phần trước. Khi tạo các loại mới, như chúng ta sẽ thấy trong các phần tiếp theo, loại này được sử dụng.

Loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
72

Một loại cần thiết khác là loại

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
72; Điều này rất giống với loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04. Loại đối tượng là loại gốc cho tất cả các loại do người dùng xác định và cung cấp một số giá trị mặc định điền vào các trường loại thuộc loại do người dùng xác định. Điều này là do các loại do người dùng xác định hoạt động khác nhau so với các loại có
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04 là loại của chúng. Như chúng ta sẽ thấy trong phần tiếp theo, các hàm như thuật toán phân giải thuộc tính được cung cấp bởi loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
72 khác biệt đáng kể so với các loại được cung cấp bởi loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04.

4.4 Các trường hợp loại tiền khai thácMinting type instances

With an assumed firm understanding of the rudiments of types, we can progress onto one of the most fundamental functions of types, which is the creation of new instances. To fully understand the process of creating new type instances, it is important to remember that just as we differentiate between built-in types and user-defined types 2, the internal structure of both differs. The

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 field is the cookie cutter for new type instances in Python. The documentation for the
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 slot as reproduced below gives a brilliant description of the function that should fill this slot.

An optional pointer to an instance creation function. If this function is NULL for a particular type, that type cannot be called to create new instances; presumably, there is some other way to create instances, like a factory function. The function signature is

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
80

The subtype argument is the type of the object being created; the

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
81 and
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
82 arguments are the positional and keyword arguments of the call to the type. Note that subtype doesn’t have to equal the type whose tp_new function is called; it may be a subtype of that type (but not an unrelated type). The
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 function should call
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
84 to allocate space for the object, and then do only as much further initialization as is absolutely necessary. Initialization that can safely be ignored or repeated should be placed in the
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
24 handler. A good rule of thumb is that for immutable types, all initialization should take place in
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23, while for mutable types, most initialization should be deferred to
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
24.

This field is inherited by subtypes but not by static types whose

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
88 is
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
89 or
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
90.

We will use the

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
38 type from the previous section as an example of a builtin type. The
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 field of the tuple type references the -
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
62 method shown in Listing 4.4, which handles the creation of new tuple objects. A new tuple object is created by dereferencing and then invoking this function.

Listing 4.4: tuple_new function for creating new tuple instances

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
1

Ignoring the first and second conditions for creating a tuple in Listing 4.4, we follow the third condition,

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
94 down the rabbit hole to find out how this works. Overlooking the optimizations abound in the
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
95 function, the segment of the function that creates a new tuple object is the
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
96 call which allocates memory for an instance of the
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
97 structure on the heap. This is where a difference between internal representation of built-in types and user-defined types comes to the fore - instances of built-ins like tuple are actually
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 structures. So what does this C struct backing a tuple object look like? It is found in the
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
99 as the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
00 typedef, and this is shown in Listing 4.5 for convenience.

Listing 4.5: PyTuple_Object definition

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
2

The

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
00 is defined as a struct having a
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
16 and an array of PyObject pointers -
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
03. This leads to a very efficient implementation as opposed to representing the instance using Python data structures.

Recall that an object is a collection of methods and data. The

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
00 in this case provides space to hold the actual data that each tuple object contains so we can have multiple instances of
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
00 allocated on the heap but these will all reference the single
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
06 type that provides the methods that can operate on this data.

Now consider a user-defined class such as in LIsting 4.6.

Listing 4.6: User defined class

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
3

The

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
07 type, as you would expect, is an object of instance
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
08. To create an instance of the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
07 type, the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
07 type is called as such -
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
11. As always, we can go down the rabbit hole to convince ourselves of what happens when the type object is called. The
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
08 type has a function reference -
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
13 that fills the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
14 field, and this is dereferenced whenever the call notation is used on an instance of
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
08. A snippet of the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
13 the function implementation is shown in listing 4.7.

Listing 4.7: A snippet of type_call function definition

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
4

In Listing 4.7, we see that when a

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
08 object instance is called, the function referenced by the
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 field is invoked to create a new instance of that type. The
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
24 function is also called if it exists to initialize the new instance. This process explains builtin types because, after all, they have their own
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 and
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
24 functions defined already, but what about user-defined types? Most times, a user does not define a
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
22 function for a new type (when defined, this will go into the
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 field during class creation). The answer to this also lies with the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
24 function that fills the
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 field of the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
08. When creating a user-defined type, such as
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
07, the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
24 function checks for the presence of base types (supertypes/classes) and when there are none, the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
29 type is added as a default base type, as shown in listing 4.8.

Liệt kê 4.8: Đoạn trích hiển thị cách
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
29 được thêm vào danh sách các cơ sở

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
5

Loại cơ sở mặc định này được xác định trong mô -đun

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
31 chứa một số giá trị mặc định cho các trường khác nhau. Trong số các mặc định này là các giá trị cho các trường
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 và
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
24. Đây là những giá trị được người phiên dịch gọi cho một loại do người dùng xác định. Trong trường hợp loại do người dùng xác định thực hiện các phương thức của nó như
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
34,
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
22, v.v., các giá trị này được gọi là thay vì loại
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
29.

Người ta có thể nhận thấy rằng chúng tôi chưa đề cập đến bất kỳ cấu trúc đối tượng nào như cấu trúc đối tượng Tuple,

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
37 và hỏi - nếu không có cấu trúc đối tượng nào được xác định cho lớp do người dùng xác định Các khe trong loại cư trú? Điều này có liên quan đến trường
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
38 - một trường số trong đối tượng loại. Tuy nhiên, các trường hợp được tạo dưới dạng pyobjects, khi giá trị bù này không khác trong loại thể hiện, nó chỉ định phần bù của từ điển thuộc tính thể hiện từ trường hợp (bản pyobject) như trong Hình 4.0 Loại, Từ điển thuộc tính có thể được đánh giá bằng cách thêm giá trị bù này vào nguồn gốc của vị trí bộ nhớ PyObject.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 4.0: Cách cấu trúc các loại do người dùng xác định.

Ví dụ: nếu một pyobject thể hiện ở

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
40 và phần bù là
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
41 thì từ điển thể hiện chứa các thuộc tính thể hiện được tìm thấy tại
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
42. Đây không phải là cách duy nhất, các trường hợp lưu trữ các thuộc tính của chúng, như chúng ta sẽ thấy trong phần sau.

4.5 Đối tượng và thuộc tính của chúngObjects and their attributes

Các loại và các thuộc tính của chúng (biến và phương thức) là trung tâm của lập trình hướng đối tượng. Thông thường, các loại và trường hợp lưu trữ các thuộc tính của chúng bằng cấu trúc dữ liệu

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
43, nhưng đây không phải là câu chuyện đầy đủ trong các trường hợp có thuộc tính
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
44 được xác định. Cấu trúc dữ liệu
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
43 này nằm ở một trong hai nơi, tùy thuộc vào loại đối tượng, như đã được đề cập trong phần trước.

  1. Đối với các đối tượng có loại
     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    08, khe cấu trúc loại
     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    47 là một con trỏ tới
     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    43 chứa các giá trị, biến và phương thức cho loại đó. Theo nghĩa thông thường hơn, chúng tôi nói trường
     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    47 của cấu trúc dữ liệu đối tượng loại là một con trỏ tới
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    04 hoặc
     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    51
     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    43.
  2. Đối với các đối tượng có loại do người dùng xác định, cấu trúc dữ liệu
     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    43 khi có mặt được đặt ngay sau cấu trúc
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    38 đại diện cho đối tượng. Giá trị
     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    38 của loại đối tượng cho phần bù từ đầu một đối tượng cho trường hợp này
     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    43 chứa các thuộc tính thể hiện.

Thực hiện truy cập từ điển đơn giản để có được các thuộc tính có vẻ đơn giản hơn thực tế. Infact, tìm kiếm các thuộc tính có liên quan nhiều hơn so với chỉ kiểm tra giá trị ____447 Ví dụ

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
08 hoặc
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
43 tại
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
38 cho các loại do người dùng xác định. Để có được sự hiểu biết đầy đủ, chúng ta phải thảo luận về giao thức mô tả - một giao thức ở trung tâm của việc tham khảo thuộc tính trong Python.
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
08 or the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
43 at
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
38 for instances of user-defined types. To get a full understanding, we have to discuss the descriptor protocol - a protocol at the heart of attribute referencing in Python.

Hướng dẫn mô tả Howto là một giới thiệu tuyệt vời cho các mô tả, nhưng phần sau đây cung cấp một mô tả chữ thảo về các mô tả. Nói một cách đơn giản, một mô tả là một đối tượng thực hiện các phương pháp đặc biệt

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
61,
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
62 hoặc
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
63 của giao thức mô tả. Liệt kê 4.9 là chữ ký cho từng phương pháp này trong Python.object that implements the
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
61,
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
62 or
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
63 special methods of the descriptor protocol. Listing 4.9 is the signature for each of these methods in Python.

Liệt kê 4.9: Phương thức giao thức mô tả

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
6

Các đối tượng chỉ thực hiện phương pháp

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
61 là các mô tả không phải là dữ liệu để chúng chỉ có thể được đọc từ sau khi khởi tạo. Ngược lại, các đối tượng thực hiện
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
61 và
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
62 là mô tả dữ liệu có nghĩa là các đối tượng mô tả đó có thể ghi được. Chúng tôi quan tâm đến việc áp dụng các mô tả vào đại diện thuộc tính đối tượng. Bộ mô tả
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
67 trong Liệt kê 4.10 là một ví dụ về bộ mô tả được sử dụng để đại diện cho một thuộc tính đối tượng.

Liệt kê 4.10: Một mô tả đơn giản để loại kiểm tra giá trị thuộc tính

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
7

Lớp mô tả

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
67 thực thi kiểm tra loại thô sơ cho bất kỳ thuộc tính nào của lớp mà nó đại diện. Điều quan trọng cần lưu ý là các mô tả chỉ hữu ích trong loại trường hợp này khi được xác định ở cấp độ lớp chứ không phải mức độ thể hiện, tức là, trong phương thức
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
34, như được hiển thị trong Liệt kê 4.11.

Liệt kê 4.11: Kiểu kiểm tra các thuộc tính ví dụ bằng cách sử dụng bộ mô tả đánh máy

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
8

Nếu người ta nghĩ cẩn thận về nó, nó chỉ có ý nghĩa đối với loại mô tả này được xác định ở cấp độ vì nếu được xác định ở mức độ, thì bất kỳ gán nào cho thuộc tính sẽ ghi đè lên người mô tả.

Một đánh giá về mã nguồn Python VM cho thấy tầm quan trọng của các mô tả. Các mô tả cung cấp cơ chế đằng sau các thuộc tính, phương pháp tĩnh, phương pháp lớp và một loạt các chức năng khác trong Python. Liệt kê 4.12, thuật toán để giải quyết một thuộc tính từ một ví dụ, ________ 470, thuộc loại do người dùng định nghĩa, là một minh họa cụ thể về tầm quan trọng của các mô tả.

Liệt kê 4.12: Thuật toán để tìm thuộc tính được tham chiếu trong một thể hiện của một loại do người dùng xác định

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
9

Thuật toán trong liệt kê 4.12 cho thấy rằng trong khi tham chiếu thuộc tính, trước tiên chúng tôi kiểm tra các đối tượng mô tả; Nó cũng minh họa cách bộ mô tả

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
67 có thể biểu thị một thuộc tính của một đối tượng - bất cứ khi nào một thuộc tính được tham chiếu, chẳng hạn như
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
72 VM tìm kiếm đối tượng loại
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
73 cho thuộc tính và trong trường hợp này, nó tìm thấy một mô tả
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
67; VM sau đó gọi phương thức
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
61 của mô tả phù hợp. Ví dụ
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
67 minh họa một mô tả nhưng có phần giả định; Để có được một liên lạc thực sự về mức độ mô tả quan trọng đối với cốt lõi của ngôn ngữ, chúng tôi xem xét một số ví dụ cho thấy cách chúng được áp dụng.

Xin lưu ý rằng thuật toán tham chiếu thuộc tính trong liệt kê 4.12 khác với thuật toán được sử dụng khi tham chiếu một thuộc tính có loại là

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04. Liệt kê 4.3 cho thấy thuật toán cho như vậy.

Liệt kê 4.13: Thuật toán để tìm một thuộc tính được tham chiếu trong một loại

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
0

Ví dụ về thuộc tính tham chiếu với các mô tả bên trong VM

Xem xét cấu trúc dữ liệu

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04 được thảo luận trước đó trong chương này. Các trường
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
79 và
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
80 trong cấu trúc dữ liệu loại có thể được điền vào bất kỳ trường hợp nào để đáp ứng giao thức mô tả. Một đối tượng chức năng là một nơi hoàn hảo để cho thấy cách thức hoạt động của nó.

Với định nghĩa loại,

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
73 Từ Liệt kê 4.11, hãy xem xét những gì xảy ra khi chúng ta tham khảo phương thức,
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
82, từ lớp như vậy -
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
83 và khi chúng ta tham chiếu cùng một phương thức từ một thể hiện như trong liệt kê 4.14.

Liệt kê 4.14: Minh họa các chức năng ràng buộc và không liên kết

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
1

Nhìn vào đoạn trích từ liệt kê 4.14, mặc dù chúng tôi dường như tham chiếu cùng một thuộc tính, các đối tượng thực tế được trả về có giá trị và loại khác nhau. Khi được tham chiếu từ loại tài khoản, giá trị trả về là loại

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
84, nhưng khi được tham chiếu từ một thể hiện của loại tài khoản, kết quả là loại
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
85. Điều này là có thể bởi vì các chức năng cũng là mô tả. Liệt kê 4.15 là định nghĩa của loại đối tượng hàm.

Liệt kê 4.15: Định nghĩa đối tượng loại chức năng

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
2

Đối tượng hàm điền vào trường

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
79 với hàm
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
87 do đó các trường hợp của loại
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
84 là các mô tả không phải là dữ liệu. Liệt kê 4.16 cho thấy việc thực hiện phương pháp
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
89.

Liệt kê 4.16: Định nghĩa đối tượng loại chức năng

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
3

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
87 có thể được gọi trong một trong hai độ phân giải thuộc tính hoặc độ phân giải thuộc tính, như được mô tả trong phần trước. Khi được gọi từ một loại, cuộc gọi đến
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
87 là như vậy
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
92 trong khi khi được gọi từ một tham chiếu thuộc tính của một thể hiện của một loại do người dùng xác định, chữ ký cuộc gọi là
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
93. Đi qua việc triển khai cho
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
87 trong Liệt kê 4.16, chúng ta sẽ thấy rằng nếu trường hợp là
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
89, thì chính hàm sẽ được trả về trong khi nếu một thể hiện được chuyển vào cuộc gọi, một đối tượng phương thức mới được tạo bằng cách sử dụng hàm và trường hợp. Điều này tổng hợp làm thế nào Python có thể trả về một loại khác cho cùng một tham chiếu chức năng bằng cách sử dụng bộ mô tả.

Trong một trường hợp khác về tầm quan trọng của các mô tả, hãy xem xét đoạn trích trong liệt kê 4.17 cho thấy kết quả của việc truy cập thuộc tính

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 từ cả một thể hiện của
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04 tích hợp và một thể hiện thuộc loại do người dùng xác định.

Liệt kê 4.17: Truy cập thuộc tính
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 từ một thể hiện của loại tích hợp và một thể hiện của một loại do người dùng xác định

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
4

Quan sát từ danh sách 4.17 rằng cả hai đối tượng không trả về loại từ điển vani khi thuộc tính

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 được tham chiếu. Đối tượng loại dường như trả về một proxy ánh xạ bất biến mà chúng ta thậm chí không thể gán. Ngược lại, trường hợp của
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04 trả về một bản đồ từ điển vani hỗ trợ tất cả các chức năng từ điển thông thường. Vì vậy, có vẻ như tham chiếu thuộc tính được thực hiện khác nhau cho các đối tượng này. Nhớ lại thuật toán được mô tả cho tìm kiếm thuộc tính từ một vài phần trở lại. Bước đầu tiên là tìm kiếm
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 của loại đối tượng cho thuộc tính, vì vậy chúng tôi tiếp tục và thực hiện điều này cho cả hai đối tượng trong liệt kê 4.18.

Liệt kê 4.18: Kiểm tra
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 trong loại đối tượng

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
5

Chúng tôi thấy rằng thuộc tính

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 được biểu thị bằng các mô tả dữ liệu cho cả hai đối tượng và đó là lý do tại sao chúng tôi có thể nhận các loại đối tượng khác nhau. Chúng tôi muốn tìm hiểu những gì xảy ra theo bìa cho mô tả này, giống như chúng tôi đã làm trong các chức năng và các phương thức ràng buộc. Một nơi tốt để bắt đầu là mô -đun
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
31 và định nghĩa cho đối tượng loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04. Một trường thú vị là trường
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
06 chứa một mảng các cấu trúc
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 (giá trị
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
08) được hiển thị trong liệt kê 4.19. Đây là bộ sưu tập các giá trị sẽ được biểu diễn bằng các mô tả trong thuộc tính
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
09
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 - Thuộc tính
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 là ánh xạ được đề cập bởi khe
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
47 của các điểm đối tượng loại.

Liệt kê 4.19: Kiểm tra
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 trong loại đối tượng

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
6

Các giá trị này không phải là những giá trị duy nhất được thể hiện bởi các mô tả trong loại dict; Có các giá trị khác như các giá trị

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
14 và
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
22 có các mô tả được tạo và chèn vào
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
47 trong quá trình khởi tạo loại. Việc chèn các giá trị này vào Dict xảy ra khi hàm
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
17 được gọi trên loại. Là một phần của quy trình khởi tạo chức năng
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
17, các đối tượng mô tả được tạo cho mỗi mục trong
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
19 và sau đó được thêm vào ánh xạ
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
47 - hàm
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
21 trong
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
31 xử lý việc này.

Trở lại thuộc tính

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 của chúng tôi, chúng tôi biết rằng sau khi khởi tạo loại, thuộc tính
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 tồn tại trong trường
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
47 của loại, vì vậy hãy để xem hàm getter của mô tả này. Hàm getter là hàm
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
26 được hiển thị trong danh sách 4.20.

Liệt kê 4.20: Hàm Getter cho một ví dụ là
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
7

Trường

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
28 trỏ đến chức năng là cổng đầu tiên của cuộc gọi nhận thuộc tính cho bất kỳ đối tượng nào. Đối với đối tượng loại, nó trỏ đến hàm
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
29. Phương thức này, lần lượt, thực hiện thuật toán tìm kiếm thuộc tính như được mô tả trong Liệt kê 4.13. Hàm được gọi bởi bộ mô tả được tìm thấy trong loại dict cho thuộc tính
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 là hàm
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
26 được đưa ra trong danh sách 4.20, và nó khá dễ hiểu. Giá trị trả lại được chúng tôi quan tâm ở đây; Đó là một proxy từ điển cho từ điển thực tế giữ thuộc tính loại; Điều này giải thích loại
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
32 được trả về khi chúng tôi truy vấn thuộc tính
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 của một đối tượng loại.

Vì vậy, những gì về thể hiện của A, một loại do người dùng xác định, thuộc tính

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 được giải quyết như thế nào? Bây giờ hãy nhớ lại rằng
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
35 là một đối tượng của loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04 vì vậy chúng tôi đi săn trong mô -đun
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
37 để xem cách tạo loại loại mới. Khe khe
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 của
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
39 chứa hàm
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
24 xử lý việc tạo các đối tượng loại mới. Xem qua tất cả các mã tạo loại trong hàm, một người vấp ngã trên đoạn trích trong danh sách 4.21.

Liệt kê 4.21: Cài đặt trường
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
06 cho loại do người dùng xác định

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
8

Giả sử điều kiện đầu tiên là đúng vì trường

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
06 chứa đầy giá trị được hiển thị trong danh sách 4.22.

Liệt kê 4.22: Các giá trị
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
43 chẳng hạn như
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
9

Khi

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
45 được gọi, trường
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
28 chứa một con trỏ tới
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
54 được gọi. Hàm này chịu trách nhiệm triển khai thuật toán tìm kiếm thuộc tính cho các loại do người dùng xác định. Trong trường hợp thuộc tính
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96, bộ mô tả được tìm thấy trong loại đối tượng
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
43 và hàm
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
61 của bộ mô tả là hàm
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
51 được xác định cho thuộc tính
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 từ liệt kê 4.21. Hàm getter
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
51 được hiển thị trong danh sách 4.23.

Liệt kê 4.23: Hàm getter cho thuộc tính
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
96 của loại do người dùng xác định

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
0

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
55 trả về một giá trị khi thể hiện đối tượng nằm trong hệ thống phân cấp kế thừa, do đó, bỏ qua rằng đối với trường hợp này là phù hợp. Đối tượng
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
56 được gọi. Liệt kê 4.24 cho thấy
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
56 và một người trợ giúp liên quan để lấy chỉ đạo thể hiện. Thực tế nhận được hàm Dict là hàm
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
58 truy vấn đối tượng cho
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
59 của nó và sử dụng nó để tính toán địa chỉ của trường hợp
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
43. Trong tình huống mà hàm này trả về giá trị null,
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
56 có thể trả về một lệnh mới cho hàm gọi.

Liệt kê 4.24: Tìm nạp thuộc tính Dicting của một thể hiện của loại người dùng được xác địnhdict attribute of an instance of a user defined type

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
1

Giải thích này tổng hợp ngắn gọn cách Python VM sử dụng các mô tả để thực hiện truy cập thuộc tính tùy chỉnh phụ thuộc loại tùy thuộc vào các loại. Mô tả có sức lan tỏa trong VM;

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
44, Phương pháp tĩnh và lớp, các thuộc tính chỉ là một số ví dụ khác về các tính năng ngôn ngữ có thể thực hiện bằng cách sử dụng các mô tả.

4.6 Thứ tự phân giải phương pháp (MRO)Method Resolution Order (MRO)

Chúng tôi đã đề cập đến MRO khi thảo luận về việc tham khảo thuộc tính mà không thảo luận về nó nhiều như vậy trong phần này, chúng tôi đi sâu hơn một chút về MRO. Các loại có thể thuộc về hệ thống phân cấp kế thừa, do đó cần có một số loại định nghĩa cách tìm kiếm các phương thức khi một loại kế thừa từ nhiều lớp; Thứ tự này được gọi là | Thứ tự phân giải phương thức (MRO) cũng thực sự được sử dụng khi tìm kiếm các thuộc tính không phải phương pháp khác như chúng ta đã thấy trong thuật toán cho độ phân giải tham chiếu thuộc tính. Bài báo, Python 2.3 Thứ tự phân giải phương thức, là một tài liệu tuyệt vời và dễ đọc về thuật toán độ phân giải phương thức được sử dụng trong Python; Một bản tóm tắt của các điểm chính được sao chép ở đây.

Python sử dụng thuật toán C3 để xây dựng thứ tự độ phân giải phương thức (còn được gọi là tuyến tính hóa ở đây) khi một loại kế thừa từ nhiều loại cơ sở. Liệt kê 4.25 cho thấy một số ký hiệu được sử dụng để giải thích thuật toán này.

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
2

Hãy xem xét loại

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 trong hệ thống phân cấp nhiều kế thừa, với
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 kế thừa từ các loại cơ sở
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
65, tuyến tính hóa
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 là tổng của
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 cộng với sự hợp nhất của tuyến tính hóa của cha mẹ và danh sách của cha mẹ -
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
68. Việc tuyến tính hóa loại
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
72 không có cha mẹ là tầm thường -
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
70. Hoạt động
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
71 được tính theo thuật toán sau:

Lấy đầu của danh sách đầu tiên, tức là, l [b1] [0]; Nếu đầu này không nằm trong đuôi của bất kỳ danh sách nào khác, thì hãy thêm nó vào tuyến tính hóa C và xóa nó khỏi danh sách trong hợp nhất, nếu không hãy nhìn vào đầu của danh sách tiếp theo và lấy nó, nếu đó là một cái đầu tốt. Sau đó lặp lại hoạt động cho đến khi tất cả các lớp đã được gỡ bỏ, hoặc không thể tìm thấy những cái đầu tốt. Trong trường hợp này, không thể xây dựng sự hợp nhất; Python 2.3 sẽ từ chối tạo lớp C và sẽ tăng một ngoại lệ.

Một số phân cấp loại không thể được tuyến tính hóa bằng thuật toán này và trong các trường hợp như vậy, VM đã ném lỗi và không tạo ra các phân cấp như vậy.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 4.1: Một hệ thống phân cấp nhiều kế thừa đơn giản.

Giả sử chúng ta có một hệ thống phân cấp kế thừa như trong Hình 4.1, thuật toán tạo MRO sẽ tiến hành như sau bắt đầu từ đầu phân cấp với

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
72,
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
35 và
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
74. Các tuyến tính hóa của
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
72,
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
35 và
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
74 là tầm thường:

Liệt kê 4.26: Tính toán tuyến tính hóa cho các loại
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
72,
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
35 và
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
74 từ Hình 4.1

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
3

Việc tuyến tính hóa

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
81 có thể được tính toán là
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
82

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
35 là một cái đầu tốt, vì vậy nó được thêm vào tuyến tính hóa và chúng ta còn lại để tính toán
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
84.
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
72 không phải là một cái đầu tốt vì nó nằm trong đuôi của
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
86, vì vậy chúng tôi chuyển sang chuỗi tiếp theo.
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
74 là một cái đầu tốt, vì vậy chúng tôi thêm nó vào tuyến tính hóa và chúng tôi còn lại để tính toán
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
88 đánh giá thành
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
72. Sự tuyến tính hóa kết quả của
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
81 -
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
91.

Giống như quy trình từ trên cao, việc tuyến tính hóa cho

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
92 được tính toán, như thể hiện trong danh sách 4.27:

Liệt kê 4.27: Tính toán tuyến tính hóa cho loại
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
92 từ Hình 4.1

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
4

Với tính tuyến tính hóa cho

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
81 và
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
92 được tính toán, chúng ta có thể tính toán rằng với
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
96 như trong danh sách 4.28.

Liệt kê 4.28: Tính toán tuyến tính hóa cho loại
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
96 từ Hình 4.1

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
5

5. Đối tượng mãCode Objects

Các đối tượng mã là các khối xây dựng thiết yếu của máy ảo Python. Các đối tượng mã gói gọn mã Bytecy ảo Python Bytecode; Chúng tôi có thể gọi mã byte là ngôn ngữ lắp ráp của máy ảo Python.

Các đối tượng mã, như tên cho thấy, đại diện cho mã Python có thể thực thi được biên dịch. Chúng tôi đã bắt gặp các đối tượng mã trước khi chúng tôi thảo luận về việc biên dịch nguồn Python. Quá trình biên dịch ánh xạ từng khối mã thành một đối tượng mã. Như được mô tả trong tài liệu Python xuất sắc:

Một chương trình Python được xây dựng từ các khối mã. Một khối là một phần của văn bản chương trình Python được thực hiện như một đơn vị. Sau đây là các khối: một mô -đun, thân hàm và định nghĩa lớp. Mỗi lệnh được gõ tương tác là một khối. Tệp tập lệnh (một tệp được cung cấp dưới dạng đầu vào tiêu chuẩn cho trình thông dịch hoặc được chỉ định là đối số dòng lệnh cho trình thông dịch) là một khối mã. Lệnh tập lệnh (lệnh được chỉ định trên dòng lệnh phiên dịch với tùy chọn ‘-c,) là một khối mã. Đối số chuỗi được truyền cho các hàm tích hợp

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
98 và
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
99 là một khối mã.

Đối tượng mã chứa các hướng dẫn mã byte có thể thay đổi trạng thái của VM Python khi chạy. Đưa ra một hàm, chúng ta có thể truy cập đối tượng mã của nó bằng thuộc tính

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
00 như trong đoạn trích sau.

Liệt kê 5.1: Đối tượng mã chức năng

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
6

Đối với các khối mã khác, người ta có thể lấy các đối tượng mã cho khối mã đó bằng cách biên dịch mã đó. Hàm biên dịch cung cấp một cơ sở cho điều này trong trình thông dịch Python. Các đối tượng mã sở hữu một số trường được sử dụng bởi vòng thông dịch khi thực thi và chúng tôi xem xét một số trong các phần này trong các phần sau.

5.1 Khám phá các đối tượng mãExploring code objects

Một cách tuyệt vời để bắt đầu với các đối tượng mã là biên dịch một hàm đơn giản và kiểm tra đối tượng mã kết quả. Chúng tôi sử dụng hàm

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
75 đơn giản được hiển thị trong Liệt kê 5.2 dưới dạng chuột lang.

Liệt kê 5.2: Các thuộc tính đối tượng mã chức năng của chức năng FizzBuzz

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
7

Các trường được hiển thị gần như tự giải thích ngoại trừ các trường

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
02 và
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
03 dường như có chứa vô nghĩa.

  1. CO_ARGCOUNT: Đây là số lượng đối số cho khối mã và chỉ có giá trị cho các khối mã chức năng. Giá trị được đặt thành số lượng của bộ đối số của khối mã Khối
     1 	>>> from dis import dis
     2         >>> def square(x):
     3         ...     return x*x
     4         ... 
     5 
     6         >>> dis(square)
     7         2           0 LOAD_FAST                0 (x)
     8                     2 LOAD_FAST                0 (x)
     9                     4 BINARY_MULTIPLY     
    10                     6 RETURN_VALUE        
    
    16 trong quá trình biên dịch. Vòng lặp đánh giá sử dụng các biến này trong quá trình thiết lập để đánh giá mã để thực hiện kiểm tra độ trễ như kiểm tra rằng tất cả các đối số đều có mặt và để lưu trữ người dân địa phương.
  2. CO_CODE: Điều này giữ chuỗi các hướng dẫn bytecode được thực hiện bởi vòng đánh giá. Mỗi chuỗi lệnh bytecode này bao gồm một đối số
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    05 và
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    06 - cho opcode nơi nó tồn tại. Ví dụ:
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    07 trả về byte đầu tiên của lệnh,
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    08 ánh xạ vào mã opcode Python
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    09.
  3. CO_CONSTS: Trường này là danh sách các hằng số như các chữ cái và giá trị số có trong đối tượng mã. Ví dụ từ phía trên cho thấy nội dung của trường này cho hàm
     1 	>>> from dis import dis
     2         >>> def square(x):
     3         ...     return x*x
     4         ... 
     5 
     6         >>> dis(square)
     7         2           0 LOAD_FAST                0 (x)
     8                     2 LOAD_FAST                0 (x)
     9                     4 BINARY_MULTIPLY     
    10                     6 RETURN_VALUE        
    
    75. Các giá trị có trong danh sách này là tích hợp để thực thi mã vì chúng là các giá trị được tham chiếu bởi opcode
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    11. Đối số toán hạng cho một lệnh bytecode như
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    11 là chỉ mục vào danh sách các hằng số này. Hãy xem xét giá trị CO_CONSTS của
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    13 cho hàm
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    14 và độ tương phản với đối tượng mã được tháo rời bên dưới. Liệt kê 5.3: Mặt cắt ngang của hướng dẫn mã byte cho chức năng FizzBuzz

     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    8

    Hãy nhớ lại rằng trong quá trình biên dịch,

     1 	>>> from dis import dis
     2         >>> def square(x):
     3         ...     return x*x
     4         ... 
     5 
     6         >>> dis(square)
     7         2           0 LOAD_FAST                0 (x)
     8                     2 LOAD_FAST                0 (x)
     9                     4 BINARY_MULTIPLY     
    10                     6 RETURN_VALUE        
    
    79 được thêm vào nếu không có câu lệnh
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    75 ở cuối hàm để chúng ta có thể nói rằng lệnh bytecode ở bù 74 là
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    11 cho giá trị
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    18. Đối số opcode là 0 và chúng ta có thể thấy rằng giá trị
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    18 có chỉ số
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    64 trong danh sách hằng số từ nơi hướng dẫn
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    11 tải nó.

  4. CO_FILENAME: Trường này, như tên gợi ý, chứa tên của tệp chứa mã nguồn đối tượng mã mà từ đó đối tượng mã.
  5. CO_FIRSTLINENO: Điều này cung cấp số dòng mà nguồn cho đối tượng mã bắt đầu. Giá trị này đóng vai trò khá thiết yếu trong các hoạt động như mã gỡ lỗi.
  6. CO_FLAGS: Trường này chỉ ra loại đối tượng mã. Ví dụ: nếu đối tượng mã là của coroutine, cờ được đặt thành
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    22. Các cờ khác như
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    23 cho biết nếu một đối tượng mã được lồng trong một khối mã khác,
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    24 cho biết nếu một khối mã có các đối số biến. Những cờ này ảnh hưởng đến hành vi của vòng lặp đánh giá trong quá trình thực hiện mã byte.
  7. Co_Lnotab: Các chuỗi byte được sử dụng để tính toán các số dòng nguồn tương ứng với lệnh tại phần bù mã byte. Ví dụ:
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    25 Hàm sử dụng điều này khi tính toán số dòng cho các hướng dẫn.
  8. Co_Varnames: Đây là số tên được xác định cục bộ trong một khối mã. Tương phản điều này với
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    26.
  9. Co_Names: Đây là một tập hợp các tên không cục bộ được sử dụng trong đối tượng mã. Ví dụ: đoạn trích trong liệt kê 5.4 tham chiếu một biến không cục bộ,
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    27. Liệt kê 5.4: Minh họa tên địa phương và không địa phương

     1 Init the indent stack with the value 0.
     2 For each logical line taking into consideration line-joining:
     3     A.  If the current line's indentation is greater than the 
     4     indentation at the top of the stack
     5         1.  Add the current line's indentation to the top of the stack.
     6         2.  Generate an INDENT token.
     7     B.  If the current line's indentation is less than the indentation
     8         at the top of the stack
     9         1. If there is no indentation level on the stack that matches the current li\
    10 ne's indentation, report an error.
    11         2.  For each value at the top of the stack, that is unequal to the current l\
    12 ine's indentation.
    13             a.  Remove the value from the top of the stack.
    14             b.  Generate a DEDENT token.
    15     C.  Tokenize the current line.
    16 For every indentation on the stack except 0, produce a DEDENT token.
    
    9

    Danh sách 5.5 là kết quả của việc hướng nội trên đối tượng mã cho hàm trong Liệt kê 5.4.

    Liệt kê 5.5: Minh họa tên địa phương và không địa phương

     1 >>>code_str = """def hello_world():
     2                     return 'hello world'
     3                 """
     4 >>> import parser
     5 >>> from pprint import pprint 
     6 >>> st = parser.suite(code_str)
     7 >>> pprint(parser.st2list(st))
     8 [257,
     9 [269,
    10 [294,
    11 [263,
    12     [1, 'def'],
    13     [1, 'hello_world'],
    14     [264, [7, '('], [8, ')']],
    15     [11, ':'],
    16     [303,
    17     [4, ''],
    18     [5, ''],
    19     [269,
    20     [270,
    21     [271,
    22         [277,
    23         [280,
    24         [1, 'return'],
    25         [330,
    26         [304,
    27             [308,
    28             [309,
    29             [310,
    30             [311,
    31                 [314,
    32                 [315,
    33                 [316,
    34                 [317,
    35                     [318,
    36                     [319,
    37                     [320,
    38                     [321,
    39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
    40     [4, '']]],
    41     [6, '']]]]],
    42 [4, ''],
    43 [0, '']]
    44 >>>  
    
    0

    Từ ví dụ này, sự khác biệt giữa

    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    28 và
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    29 là đáng chú ý.
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    29 Tài liệu tham khảo các tên được xác định cục bộ trong khi
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    26 Tài liệu tham khảo các tên không xác định địa phương. Xin lưu ý rằng chỉ trong quá trình thực hiện chương trình, không tìm thấy lỗi khi tên
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    27 không tìm thấy. Liệt kê 5.6 hiển thị các hướng dẫn mã byte cho chức năng trong Liệt kê 5.4 và nó dễ hiểu.

    Liệt kê 5.6: Hướng dẫn Bytecode cho chức năng test_non_local

     1 >>>code_str = """def hello_world():
     2                     return 'hello world'
     3                 """
     4 >>> import parser
     5 >>> from pprint import pprint 
     6 >>> st = parser.suite(code_str)
     7 >>> pprint(parser.st2list(st))
     8 [257,
     9 [269,
    10 [294,
    11 [263,
    12     [1, 'def'],
    13     [1, 'hello_world'],
    14     [264, [7, '('], [8, ')']],
    15     [11, ':'],
    16     [303,
    17     [4, ''],
    18     [5, ''],
    19     [269,
    20     [270,
    21     [271,
    22         [277,
    23         [280,
    24         [1, 'return'],
    25         [330,
    26         [304,
    27             [308,
    28             [309,
    29             [310,
    30             [311,
    31                 [314,
    32                 [315,
    33                 [316,
    34                 [317,
    35                     [318,
    36                     [319,
    37                     [320,
    38                     [321,
    39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
    40     [4, '']]],
    41     [6, '']]]]],
    42 [4, ''],
    43 [0, '']]
    44 >>>  
    
    1

    Lưu ý cách thay vì

    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    09 Như đã thấy trong ví dụ trước, chúng tôi có hướng dẫn
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    34. Sau đó, khi chúng tôi thảo luận về vòng lặp đánh giá, chúng tôi sẽ thảo luận về việc tối ưu hóa rằng vòng lặp đánh giá thực hiện việc sử dụng hướng dẫn
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    09 như tên cho thấy.

  10. Co_Nlocals: Đây là một giá trị số đại diện cho số lượng tên cục bộ được sử dụng bởi đối tượng mã. Trong ví dụ trước đây từ Liệt kê 5.4, biến cục bộ duy nhất được sử dụng là
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    65 và do đó, giá trị này là
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    37 cho đối tượng mã của hàm đó.
  11. Co_StackSize: Máy ảo Python dựa trên ngăn xếp, tức là các giá trị được sử dụng trong đánh giá và kết quả đánh giá được đọc từ và ghi vào ngăn xếp thực thi. Giá trị
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    38 này là số lượng mục tối đa tồn tại trên ngăn xếp đánh giá tại bất kỳ điểm nào trong quá trình thực hiện khối mã.
  12. CO_FREEVARS: Trường CO_FREEVARS là một tập hợp các biến miễn phí được xác định trong khối mã. Trường này chủ yếu có liên quan đến các chức năng lồng nhau hình thành việc đóng cửa. Các biến miễn phí là các biến được sử dụng trong một khối nhưng không được xác định trong khối đó; Điều này không áp dụng cho các biến toàn cầu. Khái niệm về một biến miễn phí được minh họa rõ nhất với một ví dụ, như thể hiện trong danh sách 5.7. Liệt kê 5.7: một chức năng lồng nhau đơn giản

     1 >>>code_str = """def hello_world():
     2                     return 'hello world'
     3                 """
     4 >>> import parser
     5 >>> from pprint import pprint 
     6 >>> st = parser.suite(code_str)
     7 >>> pprint(parser.st2list(st))
     8 [257,
     9 [269,
    10 [294,
    11 [263,
    12     [1, 'def'],
    13     [1, 'hello_world'],
    14     [264, [7, '('], [8, ')']],
    15     [11, ':'],
    16     [303,
    17     [4, ''],
    18     [5, ''],
    19     [269,
    20     [270,
    21     [271,
    22         [277,
    23         [280,
    24         [1, 'return'],
    25         [330,
    26         [304,
    27             [308,
    28             [309,
    29             [310,
    30             [311,
    31                 [314,
    32                 [315,
    33                 [316,
    34                 [317,
    35                     [318,
    36                     [319,
    37                     [320,
    38                     [321,
    39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
    40     [4, '']]],
    41     [6, '']]]]],
    42 [4, ''],
    43 [0, '']]
    44 >>>  
    
    2

    Trường

    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    39 trống cho đối tượng mã của hàm
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    40 trong khi hàm
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    41 chứa giá trị
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    65. Các biến miễn phí có liên quan đến nhau với các biến tế bào.

  13. CO_CELLVARS: Trường
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    43 là một tập hợp các tên cho các đối tượng lưu trữ ô trong quá trình thực hiện đối tượng mã. Lấy đoạn trích trong liệt kê 5.7, trường
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    43 của đối tượng mã cho hàm -
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    40, chỉ chứa tên -________ 165 trong khi đối tượng mã chức năng lồng nhau trống rỗng; Nhớ lại từ các cuộc thảo luận về các biến miễn phí rằng bộ sưu tập
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    39 của đối tượng mã chức năng lồng nhau chỉ bao gồm tên này -
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    65. Điều này nắm bắt mối quan hệ giữa các biến ô và các biến miễn phí - một biến miễn phí trong phạm vi lồng nhau là một biến tế bào trong phạm vi kèm theo. Các đối tượng ô đặc biệt được yêu cầu để lưu trữ các giá trị trong bộ sưu tập biến ô này trong quá trình thực hiện đối tượng mã. Điều này là như vậy bởi vì mỗi giá trị trong trường này được sử dụng bởi các đối tượng mã lồng nhau có tuổi thọ có thể vượt quá đối tượng mã kèm theo. Do đó, các giá trị như vậy yêu cầu lưu trữ ở các vị trí không được giải quyết sau khi thực hiện đối tượng mã.

Mã byte -
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
03 chi tiết hơn.

Các hướng dẫn máy ảo thực tế cho một đối tượng mã, mã byte, được chứa trong trường

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
03 của đối tượng mã như đã đề cập trước đây. Ví dụ, mã byte từ hàm
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
75 là chuỗi byte được hiển thị trong danh sách 5.7.

Liệt kê 5.7: Chuỗi mã byte cho chức năng FizzBuzz

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
3

Để có được phiên bản có thể đọc được của chuỗi byte, chúng tôi sử dụng hàm

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
25 từ mô-đun
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
25 để trích xuất bản in có thể đọc được của con người như trong Liệt kê 5.8.

Liệt kê 5,8: Giải quyết hướng dẫn Bytecode cho chức năng FizzBuzz

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
4

Cột đầu tiên của đầu ra hiển thị số dòng cho lệnh đó. Nhiều hướng dẫn có thể ánh xạ tới cùng một số dòng. Giá trị này được tính toán bằng cách sử dụng thông tin từ trường

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
02 của đối tượng mã. Cột thứ hai là phần bù của hướng dẫn đã cho từ đầu mã byte. Giả sử chuỗi bytecode được chứa trong một mảng, thì giá trị này là chỉ mục của lệnh vào mảng. Cột thứ ba là mã opcode hướng dẫn có thể đọc được thực tế của con người; toàn bộ phạm vi của các mã hóa được tìm thấy trong mô -đun
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
47. Cột thứ tư là đối số cho hướng dẫn.

Hướng dẫn

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
09 đầu tiên lấy đối số
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
64. Giá trị này là một chỉ mục vào mảng
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
29. Cột cuối cùng là giá trị của đối số - được cung cấp bởi hàm
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
25 để dễ sử dụng. Một số lập luận không có lập luận rõ ràng. Lưu ý rằng các hướng dẫn
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
60 và
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
61 không có đối số rõ ràng. Hãy nhớ lại rằng máy ảo Python dựa trên ngăn xếp nên các hướng dẫn này đọc các giá trị từ đầu ngăn xếp.

Các hướng dẫn bytecode có kích thước hai byte - một byte cho opcode và byte thứ hai cho đối số cho opcode. Trong trường hợp opcode không có đối số, thì byte đối số thứ hai được đưa ra. Máy ảo Python sử dụng mã hóa byte ít endian trên máy mà tôi hiện đang gõ cuốn sách này, do đó, 16 bit mã được cấu trúc như trong Hình 5.0 với opcode chiếm 8 bit cao hơn và đối số với opcode chiếm 8 bit thấp hơn.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 5.0: Định dạng hướng dẫn bytecode hiển thị opcode và oparg

Đôi khi, đối số cho một opcode có thể không thể phù hợp với byte đơn mặc định. Máy ảo Python sử dụng mã opcode

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
62 cho các loại đối số này. Những gì máy ảo Python làm là lấy một đối số quá lớn để phù hợp với một byte duy nhất và chia thành hai (chúng tôi cho rằng nó có thể phù hợp với hai byte ở đây, nhưng logic này dễ dàng mở rộng qua hai byte) - Byte quan trọng nhất là một đối số cho opcode
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
62 trong khi byte ít có ý nghĩa nhất là đối số với mã thực tế của nó. Opcode
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
62 sẽ đến trước mã opcode thực tế trong chuỗi các opcode và sau đó đối số có thể được xây dựng lại bằng cách chuyển sang bên phải và hoặc hay với các phần khác của đối số. Ví dụ: nếu người ta muốn chuyển giá trị 321 dưới dạng đối số cho opcode
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11, giá trị này không thể phù hợp với một byte duy nhất, do đó, opcode
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
62 được sử dụng. Biểu diễn nhị phân của giá trị này là 0B101000001, do đó, opcode công việc thực tế (load_const) lấy byte đầu tiên (1000001) làm đối số (65 trong thập phân) trong khi opcode
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
62 lấy byte tiếp theo (1) làm đối số; Do đó, chúng tôi có
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
68 là chuỗi các hướng dẫn là đầu ra.or’ing with other sections of the argument. For example, if one wanted to pass the value 321 as an argument to the
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11 opcode, this value cannot fit into a single byte, so the
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
62 opcode is used. The binary representation of this value is 0b101000001, so the actual do work opcode (LOAD_CONST) takes the first byte (1000001) as argument (65 in decimal) while the
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
62 opcode takes the next byte (1) as an argument; thus, we have
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
68 as the sequence of instructions that is output.

Tài liệu cho mô -đun DIS chứa một danh sách toàn diện và giải thích về tất cả các opcode hiện được thực hiện bởi máy ảo.

5.2 Đối tượng mã trong các đối tượng mã khácCode Objects within other code objects

Một đối tượng mã khối khác đáng xem là của một mô -đun. Giả sử chúng ta đang biên dịch một mô -đun với hàm

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
75 là nội dung, đầu ra sẽ như thế nào? Để tìm hiểu, chúng tôi sử dụng hàm
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
70 trong Python để biên dịch một mô -đun với nội dung được hiển thị trong Danh sách 5.9.

Liệt kê 5.9: Hàm lồng nhau để minh họa các đối tượng mã lồng nhau

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
5

Liệt kê 5.10 là kết quả của việc biên dịch một khối mã mô -đun.

Danh sách 5.10: Dựa thập lệnh bytecode để liệt kê 5.10

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
6

Hướng dẫn tại Byte Offset 0 Tải một đối tượng mã được lưu trữ dưới dạng tên

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
40 - Định nghĩa chức năng của chúng tôi bằng cách sử dụng lệnh
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
72. Liệt kê 5.11 là nội dung của đối tượng mã này.

Danh sách 5.11: Dựa phá lệnh bytecode cho chức năng lồng nhau từ danh sách 5.9

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
7

Như mong đợi trong một mô -đun, các trường liên quan đến các đối số đối tượng mã đều bằng không - (

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
73,
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
74). Trường
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
03 chứa các hướng dẫn mã byte, như được hiển thị trong Danh sách 5.10. Trường
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
76 là một trường thú vị. Các hằng số trong trường là một đối tượng mã và tên -
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
40 và
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
18. Đối tượng mã là của hàm, giá trị ‘f, là tên của hàm và không có giá trị trả về của hàm - hãy nhớ lại trình biên dịch Python thêm câu lệnh
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
79 vào đối tượng mã mà không có một.

Lưu ý rằng các đối tượng chức năng không được tạo trong quá trình biên dịch mô -đun. Những gì chúng ta có chỉ là các đối tượng mã - đó là trong quá trình thực thi các đối tượng mã mà hàm được tạo như đã thấy trong danh sách 5.10. Kiểm tra các thuộc tính của đối tượng mã sẽ cho thấy rằng nó cũng bao gồm các đối tượng mã khác như trong danh sách 5.12.

Danh sách 5.12: Dựa phá lệnh bytecode cho chức năng lồng nhau từ liệt kê 5.10

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
8

Logic tương tự được giải thích trước đó trên các áp dụng ở đây với đối tượng hàm chỉ được tạo trong quá trình thực hiện đối tượng mã.

5.3 Đối tượng mã trong VMCode Objects in the VM

Giống như hầu hết các loại tích hợp, có loại

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
80 xác định loại đối tượng mã và cấu trúc
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
81 cho các trường hợp đối tượng mã. Loại mã tương tự như các đối tượng loại khác đã được thảo luận trong các phần trước, vì vậy chúng tôi không sao chép nó ở đây. Liệt kê 5.13 hiển thị các cấu trúc được sử dụng để biểu diễn các trường hợp đối tượng mã.

Liệt kê 5.13: Thực hiện đối tượng mã trong C

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
9

Các trường gần như tất cả giống như các trường được tìm thấy trong các đối tượng mã Python ngoại trừ

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
38,
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
83,
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
84,
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
85,
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
86 và
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
87.
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
86 và
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
87 không thực sự là những lĩnh vực thú vị tại thời điểm này. Phần còn lại của các trường ở đây khá nhiều phục vụ cùng một mục đích với các trường trong đối tượng mã.
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
85 là một lĩnh vực tồn tại cho mục đích tối ưu hóa. Nó giữ một tham chiếu đến một đối tượng khung trước đây được sử dụng làm ngữ cảnh để thực thi đối tượng mã. Điều này sau đó được sử dụng làm khung thực thi khi đối tượng mã đó được thực hiện lại để ngăn chặn chi phí phân bổ bộ nhớ cho đối tượng khung khác.

6. Các đối tượng khungFrame Objects

Các đối tượng khung cung cấp môi trường theo ngữ cảnh để thực thi các hướng dẫn ByteCode. Lấy tập hợp các hướng dẫn bytecode trong Liệt kê 6.0 chẳng hạn,

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
91 tải các giá trị vào ngăn xếp, nhưng nó không có khái niệm về vị trí của ngăn xếp này ở đâu. Đối tượng mã cũng không có thông tin về luồng hoặc trạng thái thông dịch viên quan trọng để thực thi.

Liệt kê 6.0: Một tập hợp các hướng dẫn mã byte

 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
6

Thực hiện các đối tượng mã yêu cầu một cấu trúc dữ liệu khác cung cấp thông tin theo ngữ cảnh như vậy và đây là nơi các đối tượng khung phát vào. Người ta có thể nghĩ về đối tượng khung như một thùng chứa trong đó đối tượng mã được thực thi - nó biết về đối tượng mã và có các tham chiếu đến dữ liệu và giá trị cần thiết trong quá trình thực thi một số đối tượng mã. Như thường lệ, Python cung cấp cho chúng tôi một số cơ sở để kiểm tra các đối tượng khung bằng hàm

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
92, như thể hiện trong đoạn trích danh sách 6.1.

Liệt kê 6.1: Truy cập các đối tượng khung

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
1

Trước khi một đối tượng mã có thể được thực thi, một đối tượng khung trong đó việc thực hiện đối tượng mã đó sẽ được tạo. Một đối tượng khung như vậy chứa tất cả các không gian tên cần thiết để thực thi một đối tượng mã (cục bộ, toàn cầu và tích hợp), tham chiếu đến luồng thực thi hiện tại, ngăn xếp để đánh giá mã byte và thông tin nội dung khác quan trọng để thực thi mã byte . Để hiểu rõ hơn về đối tượng khung, chúng ta hãy xem định nghĩa của cấu trúc dữ liệu đối tượng khung từ mô -đun

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
93 và được sao chép trong liệt kê 6.2.

Liệt kê 6.2: Định nghĩa đối tượng khung trong VM

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
2

Các trường kết hợp với tài liệu trong khung không khó hiểu nhưng chúng tôi cung cấp chi tiết hơn một chút về các trường này và cách chúng liên quan đến việc thực thi mã byte.

  1. 1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    94: Trường này là một tham chiếu đến khung của đối tượng mã được thực thi trước đối tượng mã hiện tại. Đưa ra một tập hợp các đối tượng khung, các trường
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    94 của các khung này lại với nhau tạo thành một chồng các khung quay trở lại khung ban đầu. Khung ban đầu này sau đó có giá trị
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    89 trong trường
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    94 này. Ngăn khung ngầm ngầm này tạo thành những gì chúng ta gọi là
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    98.
  2. 1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    99: Trường này là một tham chiếu đến một đối tượng mã. Đối tượng mã này chứa mã byte được thực thi trong bối cảnh của khung này.
  3.  1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    00: Đây là một tham chiếu đến không gian tên tích hợp. Không gian tên này chứa các tên như
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    01,
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    02, v.v. và các giá trị tương ứng của chúng.
  4.  1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    03: Đây là một tham chiếu đến không gian tên toàn cầu của một đối tượng mã.
  5.  1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    04: Đây là một tham chiếu đến không gian tên cục bộ của đối tượng mã. Như đã đề cập trước đây, các tên này được xác định trong phạm vi của một hàm. Khi chúng tôi thảo luận về trường
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    05, chúng tôi sẽ thấy một tối ưu hóa mà Python làm khi làm việc với các tên được xác định cục bộ.
  6.  1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    06: Đây là một tham chiếu đến ngăn xếp đánh giá cho khung. Hãy nhớ lại rằng máy ảo Python là một máy ảo dựa trên ngăn xếp, vì vậy, trong quá trình đánh giá mã byte, các giá trị được đọc từ đầu ngăn xếp này và kết quả đánh giá mã byte được lưu trữ trên đỉnh của ngăn xếp này. Trường này là ngăn xếp được sử dụng trong quá trình thực thi đối tượng mã.
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    07 của đối tượng mã khung hình cho độ sâu tối đa mà cấu trúc dữ liệu này có thể phát triển.
  7.  1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    08: Như tên cho thấy, trường chỉ vào vị trí miễn phí tiếp theo của ngăn xếp giá trị đánh giá. Khi một khung mới được tạo, giá trị này được đặt thành ngăn xếp giá trị - đây là không gian đầu tiên có sẵn trên ngăn xếp vì không có mục trên ngăn xếp.
  8.  1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    09: Trường này tham chiếu một hàm được sử dụng để truy tìm việc thực thi mã Python.
  9.  1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    10,
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    11,
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    12,
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    13: là các trường được sử dụng để sổ sách kế toán để có thể thực thi mã máy phát một cách sạch sẽ. Thêm về điều này khi chúng ta thảo luận về các trình tạo python.
  10.  1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    05: Đây là một tham chiếu đến một mảng chứa đủ không gian để lưu trữ các biến di động và các biến cục bộ. Trường này cho phép vòng đánh giá tối ưu hóa tải và lưu trữ các giá trị của tên đến và từ ngăn xếp giá trị với các hướng dẫn
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    09 và
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    16. Các opcodes
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    09 và
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    16 cung cấp quyền truy cập tên nhanh hơn so với đối tác của họ
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    19 và
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    20 opcode vì họ sử dụng lập chỉ mục mảng để truy cập giá trị của tên và điều này được thực hiện trong khoảng thời gian không đổi, không giống như các đối tác của họ tìm kiếm một bản đồ cho một tên đã cho. Khi chúng tôi thảo luận về vòng lặp đánh giá, chúng tôi thấy giá trị này được thiết lập như thế nào trong quá trình bootstrapping của khung.
  11.  1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    21: Trường này tham chiếu cấu trúc dữ liệu hoạt động như một ngăn xếp được sử dụng để xử lý các vòng lặp và xử lý ngoại lệ. Đây là ngăn xếp thứ hai ngoài ngăn xếp giá trị có tầm quan trọng nhất đối với máy ảo, nhưng điều này không nhận được nhiều sự chú ý như đúng. Mối quan hệ giữa ngăn xếp khối, ngoại lệ và cấu trúc vòng lặp khá phức tạp và chúng tôi xem xét điều đó trong các chương sắp tới.

6.1 Phân bổ các đối tượng khungAllocating Frame Objects

Các đối tượng khung có mặt khắp nơi trong quá trình đánh giá mã Python - mọi khối mã được thực thi cần một đối tượng khung cung cấp một số ngữ cảnh. Các đối tượng khung mới được tạo bằng cách gọi hàm

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
22 trong mô -đun
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
23. Hàm này được gọi rất nhiều lần - bất cứ khi nào một đối tượng mã được thực thi, hai tối ưu hóa chính được sử dụng để giảm chi phí gọi chức năng này và chúng tôi xem xét ngắn gọn các tối ưu hóa này.

Đầu tiên, các đối tượng mã có một trường,

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
85 tham chiếu một đối tượng khung trơ. Khi một đối tượng mã được thực thi, khung trong đó nó được thực thi không được giải quyết ngay lập tức. Khung được duy trì khá nhiều trong
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
85 vì vậy khi tiếp theo cùng một đối tượng mã được thực thi, thời gian không được dành để phân bổ bộ nhớ cho khung thực thi mới. Các trường
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
07,
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
18,
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
99,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
06 giữ lại giá trị của chúng;
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
04,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
09,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
10,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
11,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
12 là
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
89 và
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
05 giữ lại không gian được phân bổ của nó nhưng với các biến cục bộ bị vô hiệu hóa. Các trường còn lại không giữ tham chiếu đến bất kỳ đối tượng nào. Tối ưu hóa thứ hai được sử dụng bởi máy ảo là duy trì danh sách miễn phí các đối tượng khung được phân bổ sẵn mà từ đó có thể thu được các khung để thực hiện các đối tượng mã.

Mã nguồn cho các đối tượng khung là đọc nhẹ nhàng và người ta có thể thấy cách các khái niệm khung và freelist

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
37 được thực hiện bằng cách xem xét cách các khung được phân bổ được giải quyết sau khi thực hiện đối tượng mã kèm theo. Phần thú vị của mã cho phân giải khung được hiển thị trong Liệt kê 6.3.

Liệt kê 6.3: Xử lý các đối tượng khung

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
3

Quan sát cẩn thận cho thấy người tự do sẽ chỉ phát triển khi một cuộc gọi đệ quy được thực hiện, tức là một đối tượng mã cố gắng thực hiện chính nó vì đó là lần duy nhất trường

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
38 là
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
89. Tối ưu hóa nhỏ này của việc sử dụng freelist giúp loại bỏ ở một mức độ nhất định, phân bổ bộ nhớ lặp đi lặp lại cho các cuộc gọi đệ quy như vậy.

Chương này bao gồm các điểm chính về đối tượng khung mà không đi sâu vào vòng đánh giá, được tích hợp chặt chẽ với các đối tượng khung. Một vài điều còn lại trong chương này được đề cập trong các chương tiếp theo. Ví dụ,

  1. Làm thế nào các giá trị được truyền từ khung này sang khung tiếp theo khi thực thi mã chạm vào câu lệnh
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    75?
  2. Trạng thái chủ đề là gì và trạng thái chủ đề đến từ đâu?
  3. Làm thế nào các ngoại lệ bong bóng xuống ngăn xếp của khung khi một ngoại lệ được ném vào khung thực thi? Vân vân.

Hầu hết các câu hỏi này được trả lời khi chúng ta xem xét các cấu trúc dữ liệu trạng thái thông dịch và luồng trong chương tiếp theo, và sau đó là vòng đánh giá trong các chương tiếp theo.

7. Trình thông dịch và trạng thái chủ đềInterpreter and Thread States

Như đã đề cập trong các chương trước, việc khởi tạo trình thông dịch và cấu trúc dữ liệu trạng thái luồng là một trong những bước liên quan đến bootstrap của trình thông dịch Python. Trong chương này, chúng tôi cung cấp một cái nhìn chi tiết về các cấu trúc dữ liệu này.

7.1 Trạng thái phiên dịchThe Interpreter state

Hàm

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
22 trong mô -đun
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
42 là một trong những hàm bootstrap được gọi trong quá trình khởi tạo trình thông dịch Python. Hàm này xử lý việc thiết lập thời gian chạy Python cũng như khởi tạo các cấu trúc dữ liệu trạng thái thông dịch và luồng trong số những thứ khác.

Trạng thái phiên dịch là một cấu trúc dữ liệu đơn giản, nắm bắt trạng thái toàn cầu được chia sẻ bởi một tập hợp các luồng thực thi hợp tác trong một quy trình Python. Liệt kê 7.0 là một mặt cắt ngang của định nghĩa cấu trúc dữ liệu này.

Liệt kê 7.0: Mặt cắt ngang của cấu trúc dữ liệu trạng thái thông dịch

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
4

Các trường trong danh sách 7.0 sẽ quen thuộc nếu một người bao gồm các tài liệu trước đó trong cuốn sách này và đã sử dụng Python trong một khoảng thời gian đáng kể. Chúng tôi thảo luận về một số trường của cấu trúc dữ liệu trạng thái thông dịch một lần nữa.

  •  1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    31: Có thể có nhiều trạng thái phiên dịch trong một quy trình HĐH duy nhất đang chạy thực thi Python. Trường
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    31 này tham chiếu một cấu trúc dữ liệu trạng thái phiên dịch khác trong quy trình Python nếu tồn tại và chúng tạo thành một danh sách liên kết của các trạng thái thông dịch viên, như trong Hình 7.0. Mỗi trạng thái thông dịch có bộ biến riêng sẽ được sử dụng bởi một luồng thực thi tham chiếu đến trạng thái phiên dịch. Tuy nhiên, tất cả các luồng phiên dịch trong quá trình chia sẻ cùng một không gian bộ nhớ và khóa phiên dịch toàn cầu.

    Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
    Hình 7.0: Trạng thái phiên dịch trong quá trình thực thi Python

  •  1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    32: Trường này tham chiếu trạng thái luồng của luồng hiện đang thực hiện hoặc trong trường hợp chương trình đa luồng, chủ đề hiện đang giữ khóa phiên dịch toàn cầu (GIL). Đây là một cấu trúc dữ liệu ánh xạ tới một luồng hệ điều hành thực thi.

Các trường còn lại là các biến được chia sẻ bởi tất cả các luồng hợp tác của trạng thái phiên dịch. Trường

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
33 là một bảng các mô -đun Python được cài đặt - chúng ta thấy cách trình thông dịch tìm các mô -đun này sau này khi chúng ta thảo luận về hệ thống nhập, trường
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
36 là tham chiếu đến mô -đun
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
48 tích hợp. Nội dung của mô-đun này là tập hợp các chức năng tích hợp như
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
32,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
02, v.v. và mô-đun
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
51 chứa các triển khai cho hầu hết các nội dung của mô-đun.
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
37 là một lĩnh vực tham chiếu việc thực hiện cơ chế nhập khẩu - chúng tôi nói thêm một chút về điều này khi chúng tôi thảo luận chi tiết về hệ thống nhập. ________ 753, ________ 754,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
55,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
56 và
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
57 là các trường liên quan đến codec mà Python sử dụng để mã hóa và giải mã byte và văn bản. Trình thông dịch sử dụng các giá trị trong các trường này để định vị các codec đó cũng như xử lý các lỗi liên quan đến việc sử dụng các codec đó. Một chương trình Python thực thi bao gồm một hoặc nhiều luồng thực thi. Trình thông dịch phải duy trì một số trạng thái cho từng luồng thực thi và điều này hoạt động bằng cách duy trì cấu trúc dữ liệu trạng thái luồng cho từng luồng thực thi. Chúng tôi xem xét cấu trúc dữ liệu này tiếp theo.

7.2 Trạng thái chủ đềThe Thread state

Xem xét cấu trúc dữ liệu trạng thái luồng Trong danh sách 7.1, người ta có thể thấy rằng cấu trúc dữ liệu trạng thái luồng có cấu trúc dữ liệu liên quan nhiều hơn so với cấu trúc dữ liệu trạng thái thông dịch.

Liệt kê 7.2: Mặt cắt ngang của cấu trúc dữ liệu trạng thái luồng

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
5

Một cấu trúc dữ liệu trạng thái luồng, ____ ____758 và

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
68 Các trạng thái luồng tham chiếu trường được tạo trước và ngay sau trạng thái luồng đã cho. Các trường này tạo thành một danh sách liên kết gấp đôi các trạng thái chủ đề có chung trạng thái thông dịch. Trường
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
60 tham chiếu đến trạng thái thông dịch viên trạng thái chủ đề.
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
61 tham chiếu khung thực thi hiện tại; Giá trị được tham chiếu bởi trường này thay đổi khi đối tượng mã đang thực hiện các thay đổi.

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
62, như tên cho thấy, chỉ định mức độ sâu của khung ngăn xếp trong một cuộc gọi đệ quy. Cờ
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
63 được đặt khi ngăn xếp tràn. Sau khi tràn chồng, luồng cho phép thêm 50 cuộc gọi cho các hoạt động dọn dẹp. Cờ
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
64 báo hiệu cho luồng rằng mã được thực thi không nên tràn. Cờ
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
65 và
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
66 có liên quan đến chức năng để theo dõi việc thực thi luồng.
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
67,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
68,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
69,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
70,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
71 và
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
69 là các trường được sử dụng trong quy trình xử lý ngoại lệ như sẽ thấy trong các chương tiếp theo.

Điều cần thiết là phải hiểu sự khác biệt giữa trạng thái luồng và một luồng thực tế. Trạng thái luồng chỉ là một cấu trúc dữ liệu gói gọn một số trạng thái cho một luồng thực thi. Mỗi trạng thái luồng được liên kết với một luồng HĐH gốc trong quy trình Python. Hình 7.1 là một minh họa trực quan tuyệt vời của mối quan hệ này. Chúng ta có thể thấy rằng một quy trình Python duy nhất là nơi có ít nhất một trạng thái phiên dịch và mỗi trạng thái phiên dịch là nhà của một hoặc nhiều trạng thái luồng và mỗi trạng thái luồng này ánh xạ tới một luồng thực thi hệ điều hành.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 7.1: Mối quan hệ giữa trạng thái thông dịch và trạng thái luồng

Các luồng hệ điều hành và trạng thái luồng python liên quan được tạo trong quá trình khởi tạo của các phiên dịch hoặc khi được gọi bởi mô -đun luồng. Ngay cả với nhiều luồng còn sống trong một quy trình Python, chỉ có một luồng có thể chủ động thực hiện các tác vụ ràng buộc CPU tại bất kỳ thời điểm nào. Điều này là do một luồng thực thi phải giữ GIL để thực thi mã byte trong máy ảo Python. Chương này sẽ không hoàn thành nếu không nhìn vào khái niệm Gil nổi tiếng hoặc khét tiếng vì vậy chúng tôi thực hiện điều này trong phần tiếp theo

Khóa thông dịch toàn cầu -
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73

Mặc dù các luồng Python là các luồng hệ điều hành, một luồng không thể thực thi mã byte Python trừ khi luồng đó giữ

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73. Hệ điều hành có thể lên lịch một luồng không giữ
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73 để chạy nhưng như chúng ta sẽ thấy, tất cả một luồng như vậy có thể làm là chờ để có được
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73 và chỉ khi nó giữ
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73 mới có thể thực thi mã byte. Chúng tôi xem xét toàn bộ quá trình này.

Khi trình thông dịch khởi động, một luồng thực thi chính duy nhất được tạo và không có sự tranh chấp nào cho

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73 vì không có luồng nào khác xung quanh, vì vậy luồng chính không bận tâm đến việc có được khóa.
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73 xuất hiện sau khi các chủ đề khác được sinh ra. Đoạn trích trong danh sách 7.3 là từ
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
80 và cung cấp cái nhìn sâu sắc về quá trình này trong quá trình tạo ra một chủ đề mới.

Liệt kê 7.3: Mặt cắt mã để tạo luồng mới

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
6

Đoạn trích trong danh sách 7.3 là từ hàm

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
81 được gọi để tạo một luồng mới.
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
82 là cấu trúc dữ liệu chứa tất cả thông tin mà một luồng mới cần thực hiện. Trường
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
83 tham chiếu trạng thái luồng cho luồng mới và chức năng cuộc gọi
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
84 tạo trạng thái luồng này. Chủ đề thực thi chính phải có được
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73 trước khi tạo luồng mới; Một cuộc gọi đến
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
86 xử lý việc này. Với trình thông dịch hiện đang nhận biết luồng và luồng chính giữ
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73,
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
88 được gọi để tạo luồng hệ điều hành mới. Hàm
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
89 trong mô -đun
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
80 là hàm gọi lại được gọi bởi các luồng mới khi chúng trở nên sống động. Một ảnh chụp nhanh của chức năng bootstrap này nằm trong danh sách 7.4.

Liệt kê 7.4: Mặt cắt ngang của chức năng Bootstrapping

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
7

Lưu ý cuộc gọi đến hàm

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
91 trong Liệt kê 7.4. Hàm
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
91 được xác định trong mô -đun
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
93 và nó gọi hàm
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
94, đây là chức năng cố gắng nắm giữ
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73. Một mô tả về quy trình này, như được cung cấp trong tệp nguồn, được trích dẫn trong văn bản sau.

Gil chỉ là một biến boolean (gil_locked) có quyền truy cập được bảo vệ bởi một mutex (gil_mutex) và có những thay đổi được báo hiệu bởi một biến điều kiện (Gil_cond). Gil_mutex được thực hiện trong thời gian ngắn, và do đó chủ yếu không liên quan. Trong chuỗi giữ Gil, vòng lặp chính (pyeval_evalframeex) phải có khả năng giải phóng GIL theo yêu cầu bằng một chủ đề khác. Một biến boolean dễ bay hơi (GIL_DROP_REQUEST) được sử dụng cho mục đích đó, được kiểm tra ở mỗi lượt của vòng lặp. Biến đó được đặt sau khi chờ đợi

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
96 micro giây trên
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
97 đã hết thời gian. [Trên thực tế, một biến boolean dễ bay hơi khác (eval_breaker) được sử dụng trong đó một số điều kiện thành một. Booleans dễ bay hơi là đủ như các phương tiện truyền tín hiệu giữa các luồng chỉ vì Python chỉ được chạy trên các kiến ​​trúc kết hợp bộ đệm.] Một chủ đề muốn lấy GIL trước tiên sẽ để vượt qua một lượng thời gian nhất định (
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
96 micro giây) trước khi cài đặt GiL_Drop_Request. Điều này khuyến khích thời gian chuyển đổi xác định, nhưng không thực thi nó vì các opcode có thể mất thời gian tùy ý để thực thi. Giá trị
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
96 có sẵn cho người dùng đọc và sửa đổi bằng API Python
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
00. Khi một luồng giải phóng Gil và GiL_Drop_Request được đặt, luồng đó đảm bảo rằng một luồng chờ Gil khác được lên lịch. Nó làm như vậy bằng cách chờ đợi một biến điều kiện (switch_cond) cho đến khi giá trị của gil_last_holder được thay đổi thành một thứ khác ngoài con trỏ trạng thái luồng của chính nó, cho thấy rằng một luồng khác đã lấy Gil. Điều này nghiêm cấm hành vi bất lợi về độ trễ trên các máy đa lõi trong đó một luồng sẽ giải phóng Gil một cách riêng biệt, nhưng vẫn, chạy và cuối cùng là người đầu tiên mua lại nó, làm cho các thời gian của các thời gian dài hơn nhiều so với dự kiến.

Điều trên có nghĩa là gì cho một chủ đề mới sinh ra? Hàm

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
01 trong Liệt kê 7.4 gọi hàm
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
91 xử lý yêu cầu cho
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73. Do đó, một lời giải thích cho những gì xảy ra trong yêu cầu này là - giả sử
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
35 là chủ đề chính của việc thực hiện giữ
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73 trong khi
 1 >>>code_str = """def hello_world():
 2                     return 'hello world'
 3                 """
 4 >>> import parser
 5 >>> from pprint import pprint 
 6 >>> st = parser.suite(code_str)
 7 >>> pprint(parser.st2list(st))
 8 [257,
 9 [269,
10 [294,
11 [263,
12     [1, 'def'],
13     [1, 'hello_world'],
14     [264, [7, '('], [8, ')']],
15     [11, ':'],
16     [303,
17     [4, ''],
18     [5, ''],
19     [269,
20     [270,
21     [271,
22         [277,
23         [280,
24         [1, 'return'],
25         [330,
26         [304,
27             [308,
28             [309,
29             [310,
30             [311,
31                 [314,
32                 [315,
33                 [316,
34                 [317,
35                     [318,
36                     [319,
37                     [320,
38                     [321,
39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
40     [4, '']]],
41     [6, '']]]]],
42 [4, ''],
43 [0, '']]
44 >>>  
74 là chủ đề mới vừa được sinh ra.

  1. Khi
     1 >>>code_str = """def hello_world():
     2                     return 'hello world'
     3                 """
     4 >>> import parser
     5 >>> from pprint import pprint 
     6 >>> st = parser.suite(code_str)
     7 >>> pprint(parser.st2list(st))
     8 [257,
     9 [269,
    10 [294,
    11 [263,
    12     [1, 'def'],
    13     [1, 'hello_world'],
    14     [264, [7, '('], [8, ')']],
    15     [11, ':'],
    16     [303,
    17     [4, ''],
    18     [5, ''],
    19     [269,
    20     [270,
    21     [271,
    22         [277,
    23         [280,
    24         [1, 'return'],
    25         [330,
    26         [304,
    27             [308,
    28             [309,
    29             [310,
    30             [311,
    31                 [314,
    32                 [315,
    33                 [316,
    34                 [317,
    35                     [318,
    36                     [319,
    37                     [320,
    38                     [321,
    39                         [322, [323, [3, '"hello world"']]]]]]]]]]]]]]]]]]]],
    40     [4, '']]],
    41     [6, '']]]]],
    42 [4, ''],
    43 [0, '']]
    44 >>>  
    
    74 được sinh ra,
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    94 được gọi. Điều này kiểm tra xem biến
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    97 có điều kiện được đặt. Nếu nó không được đặt thì chủ đề bắt đầu chờ.
  2. Sau khi thời gian chờ đợi trôi qua,
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    10 được đặt.
  3. Chủ đề A, sau mỗi chuyến đi qua vòng lặp thực thi, kiểm tra xem bất kỳ luồng nào khác đã đặt biến
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    10.
  4. Chủ đề A giảm
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    73 khi phát hiện biến
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    10 được đặt và cũng đặt biến
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    97.
  5. Chủ đề A cũng chờ trên một biến khác -
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    15, cho đến khi giá trị của
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    16 được đặt thành một giá trị khác với thanh trỏ trạng thái chủ đề A, chỉ ra rằng một luồng khác đã lấy
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    73.
  6. Chủ đề B hiện có
     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    73 và có thể tiếp tục thực thi mã byte.
  7. Chủ đề A chờ đợi một thời gian nhất định, đặt
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    10 và chu kỳ tiếp tục.

Để kết thúc chương này, chúng tôi tóm tắt lại mô hình của máy ảo Python mà chúng tôi đã tạo ra cho đến nay, bắt giữ khi chúng tôi chạy trình thông dịch Python bằng một tệp nguồn. Đầu tiên, trình thông dịch khởi tạo trình thông dịch và trạng thái luồng, nguồn trong tệp được biên dịch thành một đối tượng mã. Đối tượng mã sau đó được chuyển đến vòng thông báo trong đó một đối tượng khung được tạo và gắn vào luồng chính của thực thi, do đó việc thực thi đối tượng mã có thể xảy ra. Vì vậy, chúng tôi có một quy trình Python có thể chứa một hoặc nhiều trạng thái phiên dịch và mỗi trạng thái thông dịch có thể có một hoặc nhiều trạng thái luồng và mỗi trạng thái luồng tham chiếu một khung có thể tham chiếu một khung khác, v.v., tạo thành một chồng khung. Hình 7.2 cung cấp một biểu diễn trực quan của thứ tự này.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 7.2: Mối quan hệ trạng thái thông dịch, trạng thái chủ đề và khung hình

Trong chương tiếp theo, chúng tôi chỉ ra cách tất cả các phần mà chúng tôi đã mô tả cho phép thực hiện đối tượng mã Python.

8. Intermezzo: Mô -đun 1 typedef struct _ts { 2 struct _ts *prev; 3 struct _ts *next; 4 PyInterpreterState *interp; 5 6 struct _frame *frame; 7 int recursion_depth; 8 char overflowed; 9 10 char recursion_critical; 11 int tracing; 12 int use_tracing; 13 14 Py_tracefunc c_profilefunc; 15 Py_tracefunc c_tracefunc; 16 PyObject *c_profileobj; 17 PyObject *c_traceobj; 18 19 PyObject *curexc_type; 20 PyObject *curexc_value; 21 PyObject *curexc_traceback; 22 23 PyObject *exc_type; 24 PyObject *exc_value; 25 PyObject *exc_traceback; 26 27 PyObject *dict; /* Stores per-thread state */ 28 int gilstate_counter; 29 30 ... 31 } PyThreadState; 05Intermezzo: The 1 typedef struct _ts { 2 struct _ts *prev; 3 struct _ts *next; 4 PyInterpreterState *interp; 5 6 struct _frame *frame; 7 int recursion_depth; 8 char overflowed; 9 10 char recursion_critical; 11 int tracing; 12 int use_tracing; 13 14 Py_tracefunc c_profilefunc; 15 Py_tracefunc c_tracefunc; 16 PyObject *c_profileobj; 17 PyObject *c_traceobj; 18 19 PyObject *curexc_type; 20 PyObject *curexc_value; 21 PyObject *curexc_traceback; 22 23 PyObject *exc_type; 24 PyObject *exc_value; 25 PyObject *exc_traceback; 26 27 PyObject *dict; /* Stores per-thread state */ 28 int gilstate_counter; 29 30 ... 31 } PyThreadState; 05 Module

Cho đến nay, chúng tôi đã đề cập nghiêm trọng rằng máy ảo Python đối xử chung với các giá trị để đánh giá là

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38s. Điều này đặt ra câu hỏi rõ ràng - hoạt động được thực hiện một cách an toàn trên các đối tượng chung như vậy?. Ví dụ: khi đánh giá lệnh bytecode
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
22, hai giá trị
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38 được bật từ ngăn xếp đánh giá và được sử dụng làm đối số cho hoạt động Thêm, nhưng làm thế nào để máy ảo biết nếu hoạt động thêm có ý nghĩa cho cả hai giá trị?

Để hiểu làm thế nào nhiều hoạt động trên

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
38S hoạt động, chúng tôi chỉ phải xem mô -đun
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
25. Mô -đun này xác định một số chức năng hoạt động trên các đối tượng thực hiện một giao thức đối tượng nhất định. Điều này có nghĩa là ví dụ, nếu một người đã thêm hai đối tượng, thì hàm Thêm trong mô -đun này sẽ mong đợi rằng cả hai đối tượng thực hiện phương thức
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
26 của các khe
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
27. Cách tốt nhất để giải thích điều này là minh họa với một ví dụ.

Hãy xem xét khi Opcode

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
22 thêm hai số, hàm bổ sung là hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
29 của mô -đun
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
25. Liệt kê 8.1 là định nghĩa của hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
29.

Liệt kê 8.1: Chức năng Thêm chung từ Tóm tắt.c Mô -đun

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
8

Sự quan tâm của chúng tôi tại thời điểm này là trong dòng 2 của hàm

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
29 được xác định trong liệt kê 8.1 - cuộc gọi đến hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
33. Hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
33 là một hàm chung khác lấy các tham số của nó, hai số hoặc phân lớp số của số và áp dụng hàm nhị phân cho các tham số; Macro
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
35 trả về phần bù của một phương thức đã cho vào cấu trúc
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
36; Hãy nhớ lại rằng cấu trúc này là một tập hợp các phương pháp hoạt động trên các số. Định nghĩa của hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
33 chung này nằm trong liệt kê 8.2 và giải thích chuyên sâu về chức năng này ngay lập tức.

Liệt kê 8.2: Hàm Binary_op1 chung chung

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
9

  1. Hàm có ba giá trị, hai
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    38 -
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    39 và
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    40 và giá trị số nguyên, khe hoạt động, là phần bù của hoạt động đó vào cấu trúc
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    36.
  2. Các dòng 3 và 4 xác định hai giá trị
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    42 và
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    43, các cấu trúc đại diện cho một hàm nhị phân như các loại của chúng đề xuất.
  3. Từ dòng 3 đến dòng 13, chúng tôi cố gắng phân hủy hàm được đưa ra bởi đối số
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    44 cho cả
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    39 và
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    40. Trên dòng 8, có một sự kiểm tra bình đẳng của cả hai loại giá trị và nếu chúng có cùng loại, không cần phải phân hủy hàm giá trị thứ hai trong
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    44. Nếu cả hai giá trị không thuộc cùng một loại, nhưng các hàm được phân chia từ cả hai đều bằng nhau, thì giá trị
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    43 bị vô hiệu hóa.
  4. Với các hàm nhị phân được đặt ra, nếu
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    42 không phải là
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    89 thì trên dòng 15, chúng tôi kiểm tra xem
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    43 không phải là
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    89 và loại
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    40 là một kiểu con của loại
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    39. Nếu điều đó là đúng, chức năng ____ 843 được áp dụng cho cả
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    39 và
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    40. Điều này xảy ra bởi vì nếu bạn tạm dừng để suy nghĩ về nó trong một giây, phương pháp tiếp tục xuống cây kế thừa là những gì chúng tôi muốn sử dụng không phải là một người khác. Nếu
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    40 không phải là một kiểu con, thì
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    42 được áp dụng cho cả hai giá trị ở dòng 22.
  5. Đi đến dòng 27 có nghĩa là hàm
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    42 là
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    89 vì vậy chúng tôi áp dụng bất kỳ tài liệu tham khảo
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    43 nào cho cả
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    39 và
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    40 miễn là nó không phải là
     1 stmt: simple_stmt | compound_stmt
     2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
     3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
     4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
     5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
     6                 ('=' (yield_expr|testlist_star_expr))*)
     7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
     8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
     9         | '<<=' | '>>=' | '**=' | '//=')
    10 
    11 del_stmt: 'del' exprlist
    12 pass_stmt: 'pass'
    13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
    14         yield_stmt
    15 break_stmt: 'break'
    16 continue_stmt: 'continue'
    17 return_stmt: 'return' [testlist]
    18 yield_stmt: yield_expr
    19 raise_stmt: 'raise' [test ['from' test]]
    20 import_stmt: import_name | import_from
    21 import_name: 'import' dotted_as_names
    22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
    23         'import' ('*' | '(' import_as_names ')' | import_as_names))
    24 import_as_name: NAME ['as' NAME]
    25 dotted_as_name: dotted_name ['as' NAME]
    26 import_as_names: import_as_name (',' import_as_name)* [',']
    27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
    28 dotted_name: NAME ('.' NAME)*
    29 global_stmt: 'global' NAME (',' NAME)*
    30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
    31 assert_stmt: 'assert' test [',' test]
    32 
    33         ...
    
    89.
  6. Trong trường hợp cả
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    42 và
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    43 đều không chứa hàm, thì
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    68 được trả về.
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    69 chỉ là một macro tăng số lượng tham chiếu của giá trị
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    68 trước khi trả lại.

Ý tưởng được ghi lại bởi lời giải thích được đưa ra ở trên là một kế hoạch chi tiết cho cách thông dịch viên thực hiện các hoạt động trên các giá trị. Chúng tôi đã đơn giản hóa những điều một chút ở đây bằng cách bỏ qua các opcodes có thể bị quá tải. Ví dụ, biểu tượng

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
77 ánh xạ vào opcode
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
22 và áp dụng cho các chuỗi, số và một số chuỗi, nhưng chúng tôi chỉ nhìn vào nó trong bối cảnh số và các lớp con của các số. Việc triển khai
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
22 được hiển thị trong liệt kê 8.3 có thể xử lý các trường hợp khác bằng cách xem xét loại giá trị mà nó đang hoạt động và gọi các chức năng tương ứng. Đầu tiên, nếu cả hai giá trị là các ký tự unicode, trình thông dịch gọi hàm để ghép các ký tự unicode. Mặt khác, hàm ____829 được gọi. Hàm này triển khai cho thấy cách kiểm tra số và sau đó các loại trình tự áp dụng các hàm bổ sung tương ứng cho các loại khác nhau.

Liệt kê 8.3: Thực hiện Ceval của nhị phân thêm

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
0

Bỏ qua các dòng 1 và 2 khi chúng ta thảo luận về chúng khi chúng ta nói về vòng thông dịch. Những gì chúng ta thấy từ phần còn lại của đoạn trích, là khi chúng ta gặp

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
22, cổng đầu tiên là kiểm tra xem cả hai giá trị là các chuỗi để áp dụng kết nối chuỗi cho các giá trị. Hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
29 từ
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
25 sau đó được áp dụng cho cả hai giá trị nếu chúng không phải là chuỗi. Mặc dù mã có vẻ hơi lộn xộn với kiểm tra chuỗi được thực hiện trong
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
93 và số kiểm tra số và trình tự được thực hiện trong
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
25, nhưng rõ ràng những gì đang xảy ra khi chúng ta có mã hóa quá tải.

Giải thích này được cung cấp ở trên là cách trình thông dịch xử lý hầu hết các hoạt động opcode - kiểm tra các loại của các giá trị sau đó đặt lại phương thức theo yêu cầu và áp dụng cho các giá trị đối số.

9. Vòng đánh giá, 1 typedef struct _ts { 2 struct _ts *prev; 3 struct _ts *next; 4 PyInterpreterState *interp; 5 6 struct _frame *frame; 7 int recursion_depth; 8 char overflowed; 9 10 char recursion_critical; 11 int tracing; 12 int use_tracing; 13 14 Py_tracefunc c_profilefunc; 15 Py_tracefunc c_tracefunc; 16 PyObject *c_profileobj; 17 PyObject *c_traceobj; 18 19 PyObject *curexc_type; 20 PyObject *curexc_value; 21 PyObject *curexc_traceback; 22 23 PyObject *exc_type; 24 PyObject *exc_value; 25 PyObject *exc_traceback; 26 27 PyObject *dict; /* Stores per-thread state */ 28 int gilstate_counter; 29 30 ... 31 } PyThreadState; 06The evaluation loop, 1 typedef struct _ts { 2 struct _ts *prev; 3 struct _ts *next; 4 PyInterpreterState *interp; 5 6 struct _frame *frame; 7 int recursion_depth; 8 char overflowed; 9 10 char recursion_critical; 11 int tracing; 12 int use_tracing; 13 14 Py_tracefunc c_profilefunc; 15 Py_tracefunc c_tracefunc; 16 PyObject *c_profileobj; 17 PyObject *c_traceobj; 18 19 PyObject *curexc_type; 20 PyObject *curexc_value; 21 PyObject *curexc_traceback; 22 23 PyObject *exc_type; 24 PyObject *exc_value; 25 PyObject *exc_traceback; 26 27 PyObject *dict; /* Stores per-thread state */ 28 int gilstate_counter; 29 30 ... 31 } PyThreadState; 06

Cuối cùng chúng tôi đã đến ruột của máy ảo nơi máy ảo lặp lại trên một hướng dẫn mã byte đối tượng mã và thực hiện các hướng dẫn đó. Bản chất của điều này là vòng lặp

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
81 lặp lại trên các mã hóa, chuyển sang từng loại opcode để chạy mã mong muốn. Mô -đun
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
93, dài khoảng 5411 dòng, thực hiện hầu hết các chức năng cần thiết - ở trung tâm của hàm này là hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
83, hàm dài khoảng 3000 dòng chứa vòng đánh giá thực tế. Chính chức năng
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
83 này là lực đẩy chính của chúng tôi trong chương.

Mô-đun

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
93 cung cấp các tối ưu hóa dành riêng cho nền tảng như các goto có ren cũng như các tối ưu hóa máy ảo Python như dự đoán opcode. Trong bài viết này, chúng tôi quan tâm nhiều hơn đến các quy trình và tối ưu hóa máy ảo, vì vậy chúng tôi thuận tiện coi thường mọi tối ưu hóa hoặc quy trình cụ thể của nền tảng được giới thiệu ở đây miễn là nó không làm mất đi lời giải thích của chúng tôi về vòng lặp đánh giá. Chúng tôi đi sâu vào chi tiết hơn bình thường ở đây để cung cấp một lời giải thích vững chắc về cách trái tim của máy ảo được cấu trúc và hoạt động. Điều quan trọng cần lưu ý là các opcodes và việc triển khai của chúng liên tục thay đổi vì vậy mô tả này có thể không chính xác sau đó.

Trước khi bất kỳ thực hiện mã byte nào xảy ra, một số hoạt động vệ sinh như tạo và khởi tạo khung, thiết lập các biến và khởi tạo các biến máy ảo như con trỏ hướng dẫn được thực hiện. Chúng tôi xem xét một số hoạt động tiếp theo.

9.1 Đặt tên vào vị tríPutting names in place

Như đã đề cập ở trên, trái tim của máy ảo là hàm

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
83 thực thi mã byte python nhưng trước khi điều này xảy ra, rất nhiều thiết lập - kiểm tra lỗi, tạo khung và khởi tạo, v.v. - cần phải diễn ra để chuẩn bị bối cảnh đánh giá. Đây là nơi chức năng
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 cũng trong
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
93, mô -đun xuất hiện. Đối với mục đích minh họa, chúng tôi cho rằng chúng tôi đang làm việc với một mô -đun có nội dung được hiển thị trong liệt kê 9.0.

Liệt kê 9.0: Nội dung của một mô -đun đơn giản

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
1

Nhớ lại rằng các khối mã có các đối tượng mã; Các khối mã này có thể là hàm, mô -đun, v.v. Vì vậy, đối với một mô -đun có nội dung trên, chúng tôi có thể giả định rằng chúng tôi đang xử lý hai đối tượng mã - một cho mô -đun và một cho hàm

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
89 được xác định trong mô -đun.

Sau khi tạo đối tượng mã cho mô -đun trong liệt kê 9.0, đối tượng mã được tạo được thực thi thông qua một chuỗi các cuộc gọi chức năng từ mô -đun

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
90 -
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
91. Tại thời điểm này, sự quan tâm của chúng tôi nằm ở chức năng
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 với chữ ký của nó được hiển thị trong liệt kê 9.1. Nó xử lý việc thiết lập tên bắt buộc trước khi đánh giá mã byte trong
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
83. Tuy nhiên, bằng cách xem xét chữ ký chức năng cho
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 như được hiển thị trong Liệt kê 9.1, người ta có thể hỏi cách này liên quan đến việc thực thi một đối tượng mô -đun thay vì hàm thực tế.

Liệt kê 9.1: _pyeval_evalcodewithname Chữ ký chức năng

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
2

Để bao bọc một đầu của một người xung quanh này, người ta phải nghĩ chung hơn về các khối mã và đối tượng mã, không phải là chức năng hoặc mô -đun. Các khối mã có thể có bất kỳ hoặc không có đối số nào được chỉ định trong chữ ký hàm

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 - một hàm chỉ là một loại khối mã cụ thể hơn có hầu hết nếu không phải tất cả các giá trị được cung cấp. Điều này có nghĩa là trường hợp thực thi
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 cho đối tượng mã mô -đun không thú vị lắm vì hầu hết các đối số đó không có giá trị. Ví dụ thú vị xảy ra khi một cuộc gọi hàm python được thực hiện thông qua opcode
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
97. Điều này dẫn đến một cuộc gọi đến hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
98 cũng trong mô -đun
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
93. Hàm này trích xuất các đối số chức năng từ đối tượng hàm trước khi ủy thác cho hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 để thực hiện tất cả các kiểm tra tỉnh táo cần thiết - đây không phải là câu chuyện đầy đủ, nhưng chúng tôi sẽ xem xét chi tiết opcode
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
97 trong phần sau của điều này Chương.

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 là một chức năng khá lớn, vì vậy chúng tôi không bao gồm nó ở đây, nhưng hầu hết các quy trình thiết lập mà nó đi qua là khá đơn giản. Ví dụ: nhớ lại, chúng tôi đã đề cập rằng trường
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
03 của đối tượng khung cung cấp một số tối ưu hóa cho không gian tên cục bộ và các đối số chức năng không định vị chỉ được biết đến hoàn toàn khi chạy. Điều này có nghĩa là chúng tôi không thể điền vào cấu trúc dữ liệu
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
03 này mà không cần kiểm tra lỗi cẩn thận. Chính trong quá trình thiết lập này bởi hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 mà mảng được tham chiếu bởi trường
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
03 của khung được điền với toàn bộ các giá trị cục bộ. Các bước liên quan đến quá trình thiết lập mà
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 đi qua khi được gọi là liên quan đến các bước được hiển thị trong liệt kê 9.1.

Liệt kê 9.2: _PyEVAL_EVALCODEWITHNAME Các bước thiết lập

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
3

9.2 Các bộ phận của máyThe parts of the machine

Với tất cả các tên tại chỗ,

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
83 được gọi với một đối tượng khung là một trong những đối số của nó. Một cái nhìn khó hiểu về hàm này cho thấy hàm này bao gồm khá nhiều macro và biến C. Các macro là một phần không thể thiếu của vòng lặp thực thi - chúng cung cấp một phương tiện để trừu tượng hóa mã lặp đi lặp lại mà không phải chịu chi phí của một cuộc gọi chức năng và do đó chúng tôi mô tả một vài trong số chúng. Trong phần này, chúng tôi giả định rằng máy ảo không chạy với các tối ưu hóa ____108 như
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
10 được kích hoạt để chúng tôi thuận tiện bỏ qua các macro liên quan đến tối ưu hóa đó.
C macros and variables. The macros are an integral part of the execution loop - they provide a means to abstract away repetitive code without incurring the cost of a function call and as such we describe a few of them. In this section, we assume that the virtual machine is not running with
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08 optimizations such as
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
10 enabled so we conveniently ignore macros related to such optimizations.

Chúng tôi bắt đầu với một mô tả về một số biến quan trọng đối với việc thực hiện vòng lặp đánh giá.

  1. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    11: Đề cập đến khe miễn phí tiếp theo trong ngăn xếp giá trị của khung thực thi.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 9.0: Con trỏ ngăn xếp sau một giá trị duy nhất được đẩy lên ngăn xếp

  1. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    12: Đề cập đến hướng dẫn tiếp theo được thực hiện bởi vòng đánh giá. Người ta có thể nghĩ đây là bộ đếm chương trình cho máy ảo. Python 3.6 Thay đổi loại giá trị này thành
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    13 có kích thước 2 byte để xử lý kích thước lệnh bytecode mới.
  2. 1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    05: Đề cập đến Opcode Python hiện đang thực hiện hoặc mã hóa sắp được thực thi.
  3. 1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    06: Đề cập đến đối số của opcode hoặc opcode hiện đang được thực thi nếu nó có một đối số.
  4. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    16: Vòng đánh giá là một vòng lặp vô hạn được thực hiện bởi vòng lặp
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    81 vô hạn -
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    18 Vì vậy, vòng lặp cần một cơ chế để thoát ra khỏi vòng lặp và chỉ định lý do tại sao phá vỡ xảy ra. Giá trị này đề cập đến lý do thoát khỏi vòng đánh giá. Ví dụ: nếu khối mã thoát khỏi vòng lặp do câu lệnh trả về, thì giá trị này sẽ chứa trạng thái
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    19.
  5. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    03: đề cập đến một mảng các tên được xác định cục bộ.
  6. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    21: đề cập đến một danh sách các tên được sử dụng trong một khối mã nhưng không được xác định trong khối mã đó.
  7. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    22: đề cập đến giá trị trả về từ thực thi khối mã.
  8. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    23: Tài liệu tham khảo đối tượng mã chứa mã byte sẽ được thực thi bởi vòng lặp đánh giá.
  9. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    24: Điều này tham chiếu tên của tất cả các giá trị trong khối mã của khung thực thi.
  10. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    25: Điều này tham chiếu các hằng số được sử dụng bởi các đối tượng mã.

Các macro sau đây đóng một vai trò quan trọng trong vòng đánh giá.

  1. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    26: Mở rộng sang tuyên bố
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    27. Điều này phù hợp với opcode hiện tại với khối mã thực hiện opcode.
  2. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    28: Mở rộng đến
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    29. Điều này cùng với macro tiếp theo -
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    30, xử lý luồng kiểm soát của vòng đánh giá sau khi một opcode được thực thi.
  3. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    30: Mở rộng sang một bước nhảy sang nhãn
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    32 trong vòng lặp đánh giá
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    81.

Với việc giới thiệu opcode byte tiêu chuẩn 2 trong Python 3.6, bộ macro sau đây được sử dụng để xử lý quyền truy cập mã.

  1. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    34: Macro này cung cấp phần bù byte của hướng dẫn hiện tại vào mảng hướng dẫn. Điều này mở rộng đến
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    35.
  2. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    36: Điều này cập nhật biến
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    05 và
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    06 với giá trị của opcode và đối số của lệnh bytecode tiếp theo sẽ được thực thi. Macro này mở rộng sang đoạn trích sau đây.
Liệt kê 9.3: Mở rộng macro
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
39

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
4

Các macro

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
40 và
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
41 xử lý các thao tác bit để trích xuất opcode và đối số. Hình 9.0 cho thấy cấu trúc của một hướng dẫn mã byte với đối số với mã opcode lấy tám bit thấp hơn và bản thân opcode lấy tám bit trên do đó
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
40 mở rộng lên
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
43 do đó trích xuất byte quan trọng nhất từ ​​lệnh bytecode trong khi
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
41 byte ít có ý nghĩa nhất.

  1. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    46: Macro này mở rộng lên
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    47 và thực hiện một bước nhảy tuyệt đối đến một phần bù cụ thể trong luồng mã byte.
  2. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    48: Macro này mở rộng lên
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    49 và thực hiện một bước nhảy tương đối từ phần bù lệnh hiện tại sang một điểm khác trong luồng lệnh bytecode.
  3. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    50: Opcode này cùng với opcode
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    51 thực hiện dự đoán opcode của vòng đánh giá Python. Opcode này mở rộng sang đoạn trích sau đây. Danh sách 9.4: Mở rộng macro
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    50

     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    5

  4. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    51: Macro này mở rộng lên
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    54.

Hai macro cuối cùng được xác định ở trên dự đoán opcode. Khi vòng đánh giá gặp macro

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
50; Trình thông dịch giả định rằng hướng dẫn tiếp theo sẽ được thực thi là
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
56. Các macro kiểm tra xem điều này có thực sự hợp lệ không và nếu việc tìm nạp hợp lệ opcode và đối số thực tế sau đó nhảy vào nhãn
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
57 trong đó
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
58 là trình giữ chỗ cho mã opcode thực tế. Ví dụ: nếu chúng ta đã gặp phải một dự đoán, chẳng hạn như
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
59 thì đối số câu lệnh
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
60 sẽ là
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
61 nếu dự đoán đó là hợp lệ. Việc kiểm tra mã nguồn cho hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
83 tìm thấy nhãn
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
63 mở rộng lên
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
61, vì vậy về dự đoán thành công về hướng dẫn này; Có một bước nhảy vào nhãn này nếu không thực thi bình thường vẫn tiếp tục. Dự đoán này tiết kiệm chi phí liên quan đến việc chuyển tiếp thêm của tuyên bố
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
65 sẽ xảy ra với việc thực thi mã thông thường.

Bộ macro tiếp theo mà chúng tôi quan tâm là các macro thao tác ngăn xếp xử lý việc đặt và tìm nạp các giá trị từ ngăn xếp giá trị của một đối tượng khung. Những macro này khá giống nhau, và đoạn trích sau đây cho thấy một vài ví dụ.

  1. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    66: Điều này trả về số lượng mục trên ngăn xếp. Macro mở rộng lên
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    67.
  2. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    68: Trả về mục cuối cùng trên ngăn xếp. Điều này mở rộng đến
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    69.
  3. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    70: Điều này trả về mục áp chót trên ngăn xếp. Điều này mở rộng lên
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    71.
  4. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    72: Điều này đặt mặt hàng, v, trên ngăn xếp. Nó mở rộng lên
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    73. Một bí danh hiện tại cho macro này là
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    74.
  5. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    75: Điều này loại bỏ và trả về một mục từ ngăn xếp. Điều này mở rộng lên
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    76. Một bí danh hiện tại cho điều này là macro
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    77.

Tập hợp các macro cuối cùng của chúng tôi là những macro xử lý thao tác biến đổi cục bộ. Các macro này,

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
78 và
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
79 được sử dụng để có và đặt các giá trị trong mảng
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
03.

  1. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    81: Điều này mở rộng lên
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    82. Điều này xử lý việc tìm nạp các tên được xác định cục bộ từ mảng cục bộ.
  2. 1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    83: Điều này mở rộng sang đoạn trích trong liệt kê 9.5. Macro này đặt phần tử
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    84 của mảng cục bộ thành giá trị được cung cấp. Danh sách 9,5: Mở rộng macro
    1 def fizzbuzz(n):
    2     if n % 3 == 0 and n % 5 == 0:
    3         return 'FizzBuzz'
    4     elif n % 3 == 0:
    5         return 'Fizz'
    6     elif n % 5 == 0:
    7         return 'Buzz'
    8     else:
    9         return str(n)
    
    83

     1 stmt = FunctionDef(identifier name, arguments args,
     2                    stmt* body, expr* decorator_list, expr? returns)
     3       | AsyncFunctionDef(identifier name, arguments args,
     4                          stmt* body, expr* decorator_list, expr? returns)
     5 
     6       | ClassDef(identifier name,
     7          expr* bases,
     8          keyword* keywords,
     9          stmt* body,
    10          expr* decorator_list)
    11       | Return(expr? value)
    12 
    13       | Delete(expr* targets)
    14       | Assign(expr* targets, expr value)
    15       | AugAssign(expr target, operator op, expr value)
    16       -- 'simple' indicates that we annotate simple name without parens
    17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
    18 
    19       -- use 'orelse' because else is a keyword in target languages
    20       | For(expr target, expr iter, stmt* body, stmt* orelse)
    21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
    22       | While(expr test, stmt* body, stmt* orelse)
    23       | If(expr test, stmt* body, stmt* orelse)
    24       | With(withitem* items, stmt* body)
    25       | AsyncWith(withitem* items, stmt* body)
    
    6

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
86 và
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
87 có liên quan đến việc xử lý ngoại lệ và chúng tôi xem xét chúng trong các phần tiếp theo.

9.3 Vòng đánh giáThe Evaluation loop

Cuối cùng chúng ta đã đến trung tâm của máy ảo - vòng lặp nơi các mã hóa được đánh giá. Việc triển khai khá chống khí hậu vì không có gì đặc biệt ở đây, chỉ là một vòng lặp ____8881 không bao giờ kết thúc và một tuyên bố

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
65 lớn phù hợp với các opcode. Để có được sự hiểu biết cụ thể về tuyên bố này, chúng tôi xem xét việc thực hiện chức năng Hello World đơn giản trong liệt kê 9.6.

Liệt kê 9.6: Hello Hello World Python Chức năng

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
7

Liệt kê 9.7 cho thấy việc tháo gỡ chức năng từ Liệt kê 9.6 và chúng tôi minh họa việc đánh giá bộ hướng dẫn này.

Liệt kê 9.7: Tháo gỡ chức năng trong Liệt kê 9.6

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
8

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 9.1: Đường dẫn đánh giá cho hướng dẫn
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
34 và
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11

Hình 9.1 cho thấy đường dẫn đánh giá cho các hướng dẫn

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
34 và
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11. Các khối thứ hai và thứ ba trong cả hai hình ảnh của Hình 9.2 đại diện cho các nhiệm vụ vệ sinh được thực hiện trên mọi lần lặp của vòng lặp đánh giá. Các kiểm tra xử lý tín hiệu và ____773 và tín hiệu đã được thảo luận trong chương trước về trình thông dịch và trạng thái luồng - chính trong các kiểm tra này, việc thực thi luồng có thể từ bỏ quyền kiểm soát
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73 cho một luồng khác để thực thi.
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
32 là nhãn mã ngay sau
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73 và mã xử lý tín hiệu tồn tại để phục vụ như một điểm đến nhảy khi vòng lặp muốn bỏ qua các kiểm tra trước đó như chúng ta sẽ thấy khi chúng ta xem hướng dẫn
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11.

Hướng dẫn đầu tiên -

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
34 được đánh giá bằng câu lệnh Case Load_Global của câu lệnh
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
65. Việc triển khai opcode này giống như các opcode khác là một loạt các câu lệnh C và các cuộc gọi chức năng có liên quan đáng ngạc nhiên, như thể hiện trong liệt kê 9.8. Việc triển khai opcode tải giá trị được xác định bởi tên đã cho từ không gian tên toàn cầu hoặc tích hợp lên ngăn xếp đánh giá.
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
06 là chỉ mục vào tuple chứa tất cả các tên được sử dụng trong khối mã -
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
26.

Liệt kê 9.8: Triển khai Load_Global

 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
9

Thuật toán tra cứu cho opcode

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
34 lần đầu tiên cố gắng tải tên từ các trường
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
03 và
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
00 nếu chúng là đối tượng Dict nếu không, nó cố gắng tìm nạp giá trị liên quan đến tên Giao thức để tìm nạp giá trị liên quan đến một tên nhất định. Giá trị, nếu được tìm thấy, được tải vào ngăn xếp đánh giá bằng cách sử dụng lệnh PUSH (v) khác, một lỗi được đặt và thực thi nhảy vào nhãn để xử lý mã lỗi đó.

Như biểu đồ dòng chảy cho thấy, macro Dispatch (), bí danh cho câu lệnh

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
29, được gọi sau khi giá trị được đẩy lên ngăn xếp đánh giá.

Sơ đồ thứ hai, được dán nhãn

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
76 trong Hình 9.1, cho thấy việc thực hiện
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11. Liệt kê 9.9 là việc triển khai opcode
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11.

Liệt kê 9.9:
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11 triển khai opcode

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
0

Điều này đi qua thiết lập tiêu chuẩn là

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
34 nhưng sau khi thực hiện,
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
014 được gọi là thay vì
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
015. Điều này gây ra một bước nhảy vào nhãn mã
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
32 từ đó việc thực thi vòng lặp tiếp tục bỏ qua tín hiệu và GIL kiểm tra trên lần lặp tiếp theo. Các opcodes có các triển khai thực hiện các cuộc gọi hàm C tạo ra macro
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
28 trong khi các mã hóa như
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
34 không thực hiện các cuộc gọi hàm C trong quá trình triển khai của chúng sử dụng macro
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
30. Điều này có nghĩa là luồng thực thi chỉ có thể mang lại
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
73 sau khi thực thi các opcode thực hiện các cuộc gọi chức năng C.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 9.2: Đường dẫn đánh giá cho hướng dẫn
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
97 và
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
022

Hướng dẫn tiếp theo là opcode

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
97, như được hiển thị trong hình ảnh đầu tiên từ Hình 9.2. Việc biên dịch phát ra mã opcode này cho một cuộc gọi hàm chỉ với các đối số vị trí. Liệt kê 9.10 là việc triển khai cho opcode này. Trọng tâm của việc triển khai Opcode là
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
024.
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
06 là số lượng đối số được truyền cho hàm và hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
026 đọc rằng số lượng giá trị từ ngăn xếp đánh giá.

Liệt kê 9.10:
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
97 Thực hiện Opcode

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
1

Lệnh tiếp theo được hiển thị trong Sơ đồ 4 của Hình 9.2 là lệnh

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
022 loại bỏ một giá trị từ đầu ngăn xếp đánh giá - điều này xóa bất kỳ giá trị nào được đặt trên ngăn xếp theo lệnh gọi hàm trước.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 9.3: Đường dẫn đánh giá cho hướng dẫn
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11 và
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
61

Bộ hướng dẫn tiếp theo là cặp

1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11 và
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
61 được hiển thị trong sơ đồ 5 và 6 của Hình 9.3. Opcode
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11 tải giá trị
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
18 lên ngăn xếp đánh giá; Đây là giá trị mà
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
61 sẽ trở lại. Hai cái này luôn đi cùng nhau khi một hàm không trả về rõ ràng bất kỳ giá trị nào. Chúng tôi đã xem xét các cơ chế của hướng dẫn
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11. Lệnh
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
61 bật đỉnh của ngăn xếp vào biến
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
22, đặt mã trạng thái
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
039 thành
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
19 và sau đó thực hiện một bước nhảy vào nhãn mã
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
041 nơi tiếp tục thực hiện. Nếu không có ngoại lệ, việc thực hiện sẽ thoát ra khỏi vòng lặp
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
81 và trả về
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
22.

Lưu ý rằng rất nhiều đoạn mã mà chúng tôi đã xem xét có bước nhảy

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
044, nhưng chúng tôi đã cố tình thảo luận về các lỗi và ngoại lệ cho đến nay. Chúng tôi sẽ xem xét xử lý ngoại lệ trong chương tiếp theo. Mặc dù mã byte của chức năng đã xem xét trong phần này là tương đối tầm thường, nhưng nó gói gọn hành vi vani của vòng đánh giá. Các opcodes khác có thể có các triển khai phức tạp hơn, nhưng bản chất của việc thực hiện giống như được mô tả ở trên.

Tiếp theo, chúng tôi xem xét một số opcodes thú vị khác được hỗ trợ bởi máy ảo Python.

9.4 Một mẫu OpcodesA sampling of opcodes

Máy ảo Python có khoảng 157 opcode, vì vậy chúng tôi chọn ngẫu nhiên một vài mã hóa và khử cấu trúc để có thêm cảm giác về cách thức hoạt động của các opcodes này. Một số ví dụ về các opcode này bao gồm:

  1. 1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    72: Như tên cho thấy, opcode tạo một đối tượng hàm từ các giá trị trên ngăn xếp đánh giá. Xem xét một mô -đun chứa các chức năng được hiển thị trong Liệt kê 9.11. Liệt kê 9.11: Định nghĩa chức năng trong một mô -đun

     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    2

    Bỏ qua đối tượng mã từ phần biên dịch mô -đun cung cấp cho tập hợp các hướng dẫn mã byte được hiển thị trong danh sách 9.12

    Liệt kê 9.11: Tháo đối tượng mã từ Liệt kê 9.11

     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    3

    Chúng ta có thể thấy rằng opcode

    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    72 xuất hiện hai lần trong chuỗi các hướng dẫn mã byte - một cho mỗi định nghĩa hàm trong mô -đun. Việc triển khai
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    72 tạo ra một đối tượng hàm và sau đó lưu trữ hàm trong không gian tên
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    048 bằng cách sử dụng tên định nghĩa chức năng. Lưu ý rằng các đối số mặc định được đẩy trên ngăn xếp khi các đối số đó được xác định. Việc triển khai
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    72 tiêu thụ các giá trị này bằng cách và điều chỉnh
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    06 với các giá trị bitmask và popping từ ngăn xếp phù hợp.

    Liệt kê 9.12:
    1 >>> import ast
    2 >>> import pprint
    3 >>> node = ast.parse(code_str, mode="exec")
    4 >>> ast.dump(node)
    5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
    6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
    7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
    8 'returns=None)])')
    
    72 Thực hiện Opcode

     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    4

    Các cờ trên biểu thị những điều sau đây.

    1.  1     typedef struct _ts {
       2         struct _ts *prev;
       3         struct _ts *next;
       4         PyInterpreterState *interp;
       5 
       6         struct _frame *frame;
       7         int recursion_depth;
       8         char overflowed; 
       9                         
      10         char recursion_critical; 
      11         int tracing;
      12         int use_tracing;
      13 
      14         Py_tracefunc c_profilefunc;
      15         Py_tracefunc c_tracefunc;
      16         PyObject *c_profileobj;
      17         PyObject *c_traceobj;
      18 
      19         PyObject *curexc_type;
      20         PyObject *curexc_value;
      21         PyObject *curexc_traceback;
      22 
      23         PyObject *exc_type;
      24         PyObject *exc_value;
      25         PyObject *exc_traceback;
      26 
      27         PyObject *dict;  /* Stores per-thread state */
      28         int gilstate_counter;
      29 
      30         ... 
      31     } PyThreadState;
      
      052: Một bộ đối tượng đối số mặc định theo thứ tự vị trí nằm trên ngăn xếp.
    2.  1     typedef struct _ts {
       2         struct _ts *prev;
       3         struct _ts *next;
       4         PyInterpreterState *interp;
       5 
       6         struct _frame *frame;
       7         int recursion_depth;
       8         char overflowed; 
       9                         
      10         char recursion_critical; 
      11         int tracing;
      12         int use_tracing;
      13 
      14         Py_tracefunc c_profilefunc;
      15         Py_tracefunc c_tracefunc;
      16         PyObject *c_profileobj;
      17         PyObject *c_traceobj;
      18 
      19         PyObject *curexc_type;
      20         PyObject *curexc_value;
      21         PyObject *curexc_traceback;
      22 
      23         PyObject *exc_type;
      24         PyObject *exc_value;
      25         PyObject *exc_traceback;
      26 
      27         PyObject *dict;  /* Stores per-thread state */
      28         int gilstate_counter;
      29 
      30         ... 
      31     } PyThreadState;
      
      053: Từ điển của các tham số chỉ có giá trị mặc định có trên ngăn xếp.
    3.  1     typedef struct _ts {
       2         struct _ts *prev;
       3         struct _ts *next;
       4         PyInterpreterState *interp;
       5 
       6         struct _frame *frame;
       7         int recursion_depth;
       8         char overflowed; 
       9                         
      10         char recursion_critical; 
      11         int tracing;
      12         int use_tracing;
      13 
      14         Py_tracefunc c_profilefunc;
      15         Py_tracefunc c_tracefunc;
      16         PyObject *c_profileobj;
      17         PyObject *c_traceobj;
      18 
      19         PyObject *curexc_type;
      20         PyObject *curexc_value;
      21         PyObject *curexc_traceback;
      22 
      23         PyObject *exc_type;
      24         PyObject *exc_value;
      25         PyObject *exc_traceback;
      26 
      27         PyObject *dict;  /* Stores per-thread state */
      28         int gilstate_counter;
      29 
      30         ... 
      31     } PyThreadState;
      
      054: Một từ điển chú thích nằm trên ngăn xếp.
    4.  1     typedef struct _ts {
       2         struct _ts *prev;
       3         struct _ts *next;
       4         PyInterpreterState *interp;
       5 
       6         struct _frame *frame;
       7         int recursion_depth;
       8         char overflowed; 
       9                         
      10         char recursion_critical; 
      11         int tracing;
      12         int use_tracing;
      13 
      14         Py_tracefunc c_profilefunc;
      15         Py_tracefunc c_tracefunc;
      16         PyObject *c_profileobj;
      17         PyObject *c_traceobj;
      18 
      19         PyObject *curexc_type;
      20         PyObject *curexc_value;
      21         PyObject *curexc_traceback;
      22 
      23         PyObject *exc_type;
      24         PyObject *exc_value;
      25         PyObject *exc_traceback;
      26 
      27         PyObject *dict;  /* Stores per-thread state */
      28         int gilstate_counter;
      29 
      30         ... 
      31     } PyThreadState;
      
      055: Một tuple chứa các ô cho các biến miễn phí, thực hiện việc đóng là trên ngăn xếp.

    Hàm

     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    056 thực sự tạo ra một đối tượng hàm được triển khai trong mô -đun ____1057 và việc triển khai của nó khá đơn giản. Hàm khởi tạo một đối tượng chức năng và đặt các giá trị trên đối tượng hàm.

  2.  1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    058: Opcode này xử lý các tham chiếu thuộc tính như
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    059. Giả sử chúng ta có một đối tượng thể hiện
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    65, một tham chiếu thuộc tính như
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    061 dịch sang tập hợp các opcode được hiển thị trong liệt kê 9.13. Liệt kê 9.13: Opcodes cho một tham chiếu thuộc tính

     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    5

    Việc triển khai opcode ____1058 khá đơn giản và được hiển thị trong liệt kê 9,14.

    Liệt kê 9,14:
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    058 Thực hiện Opcode

     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    6

    Chúng tôi đã xem xét chức năng

     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    064 trong chương về các đối tượng. Hàm này trả về giá trị của một thuộc tính đối tượng sau đó được tải vào ngăn xếp. Người ta có thể xem lại chương về các đối tượng để có được chi tiết về cách hoạt động của chức năng này.

  3.  1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    065: Opcode này rất giống nhau về chức năng với mã opcode
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    97 đã được thảo luận trước đây nhưng được sử dụng cho các cuộc gọi chức năng với các đối số từ khóa. Liệt kê 9.15 là việc triển khai cho opcode này. Lưu ý cách một trong những thay đổi đáng kể từ việc triển khai opcode
     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    97 là một tuple của các tên hiện được thông qua như một trong những đối số khi
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    026 được gọi. Liệt kê 9.15:
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    065 triển khai opcode

     1 static expr_ty
     2 ast_for_ifexpr(struct compiling *c, const node *n)
     3 {
     4     /* test: or_test 'if' or_test 'else' test */
     5     expr_ty expression, body, orelse;
     6 
     7     assert(NCH(n) == 5);
     8     body = ast_for_expr(c, CHILD(n, 0));
     9     if (!body)
    10         return NULL;
    11     expression = ast_for_expr(c, CHILD(n, 2));
    12     if (!expression)
    13         return NULL;
    14     orelse = ast_for_expr(c, CHILD(n, 4));
    15     if (!orelse)
    16         return NULL;
    17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
    18                  c->c_arena);
    19 }
    
    7

Tên là các đối số từ khóa của cuộc gọi hàm và chúng được sử dụng trong

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 để xử lý thiết lập trước khi đối tượng mã cho hàm được thực thi.

Điều này giới hạn giải thích của chúng tôi về vòng đánh giá. Như chúng ta đã thấy, các khái niệm đằng sau vòng đánh giá không phức tạp - mỗi mã hóa có các triển khai có trong

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
08. Các triển khai này là các hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
072 thực tế. Hai lĩnh vực quan trọng mà chúng tôi chưa chạm vào là xử lý ngoại lệ và ngăn xếp khối, hai khái niệm liên quan mật thiết mà chúng tôi xem xét trong chương sau.

10. ngăn xếp khốiThe Block Stack

Một trong những cấu trúc dữ liệu không nhận được nhiều độ che phủ như nên là ngăn xếp khối, ngăn xếp khác trong một đối tượng khung. Hầu hết các cuộc thảo luận của VM Python đề cập đến ngăn xếp khối một cách thông qua nhưng sau đó tập trung vào ngăn xếp đánh giá. Tuy nhiên, ngăn xếp khối là rất quan trọng để xử lý ngoại lệ. Có lẽ có các phương pháp thực hiện xử lý ngoại lệ khác nhưng sẽ trở nên rõ ràng khi chúng ta tiến bộ qua chương này, sử dụng ngăn xếp, ngăn xếp khối, khiến việc thực hiện xử lý ngoại lệ. Việc xử lý ngăn xếp và xử lý ngoại lệ được đan xen đến mức người ta sẽ không hiểu đầy đủ sự cần thiết của ngăn xếp khối mà không thực sự xem xét xử lý ngoại lệ. Các vòng lặp cũng sử dụng ngăn xếp khối, nhưng rất khó để thấy một lý do cho các ngăn xếp khối với các vòng cho đến khi người ta nhìn vào cách các vòng lặp xây dựng như

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
073 tương tác với các trình xử lý ngoại lệ. Ngăn xếp khối làm cho việc thực hiện các tương tác như vậy trở thành một vấn đề đơn giản.

Ngăn xếp khối là trường cấu trúc dữ liệu ngăn xếp trong một đối tượng khung. Giống như ngăn xếp đánh giá, các giá trị được đẩy đến và bật ra từ ngăn xếp khối trong quá trình thực hiện mã khung hình khung. Tuy nhiên, ngăn xếp khối chỉ được sử dụng để xử lý các vòng và ngoại lệ. Cách tốt nhất để giải thích ngăn xếp khối là với một ví dụ, vì vậy chúng tôi minh họa với cấu trúc

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
074 đơn giản trong một vòng lặp như thể hiện trong đoạn trích trong danh sách 10.0.

Liệt kê 10.0: Hàm Python đơn giản với xử lý ngoại lệ

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
8

Liệt kê 10.1 là việc tháo gỡ mã từ Liệt kê 10.0.

Liệt kê 10.1: Tháo gỡ chức năng trong Danh sách 10.0

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
9

Sự kết hợp của một vòng lặp

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
81 và
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
076 dẫn đến rất nhiều hướng dẫn ngay cả đối với một chức năng đơn giản như liệt kê 10.1 cho thấy. Các opcodes quan tâm ở đây là các mã hóa
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
077 và ____1078 để chúng tôi xem xét các triển khai của những điều này để có được ý chính của những gì nó làm (tất cả
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
079 Opcodes Map cho cùng một triển khai).

Việc triển khai cho opcode

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
077 là một cuộc gọi chức năng đơn giản -
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
081. Các đối số khá tự giải thích -
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
40 là khung,
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
05 là opcode hiện đang thực hiện,
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
084 là Delta hướng dẫn cho lệnh tiếp theo sau khối đó (đối với mã trên, Delta là 50 cho Cài đặt Có bao nhiêu mục trên ngăn xếp giá trị của khung. Cuộc gọi chức năng tạo ra một khối mới và đẩy nó vào ngăn xếp khối. Thông tin có trong khối này là đủ để máy ảo tiếp tục thực hiện nếu có điều gì đó xảy ra khi ở trong khối đó. Liệt kê 10.2 là việc thực hiện chức năng này.

Listing 10.2: Block setup code

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
0

The handler in Listing 10.2 is the pointer to the next instruction that should be executed after the

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
079 block. A visual representation of the example from above is illustrative - figure 10.0 shows this using a subset of the bytecode.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Figure 10.0: How the block stack changes with SETUP_* instructions

Figure 10.0 shows how the block stack varies during the execution of instructions.
The first diagram of figure 10.0 shows a single

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
077 block placed on the block stack after the execution of the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
077 opcode. The instruction at offset 36 is the handler for this block, so when this stack is popped during normal execution, the interpreter will jump to that offset and continue execution. Another block is pushed onto the block stack during the execution of the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
078 opcode. We can see that as the stack is Last In First Out data structure, the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
090 block will be the first out - recall that finally must be executed regardless of the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
073 statement.

A simple illustration of the use of a block stack is when the break statement is encountered while inside the exception handler within the loop. The

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
16 variable is set to
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
093 during the execution of the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
094 and a jump to the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
041 code label, where the block stack unwinding is handled, is performed.

The second diagram of figure 10.0 shows this. Unwinding is just a fancy name for popping blocks on the stack and executing their handler. So in this case, the

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
078 block is popped off the stack, and the interpreter jumps to its handler at bytecode offset 22. Execution continues from that offset till the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
097 statement. Since the
1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
16 code is a
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
093; a jump is executed to the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
041 code label once again where more stack unwinding happens - the loop block is left on the stack. This time around (not shown in figure 10.0), the block popped from the stack has a handler at byte offset 36, so the execution continues at that bytecode offset, thus exiting the loop.

The use of the block stack dramatically simplifies the implementation of the virtual machine implementation. If loops are not implemented with a block stack, an opcode such as the

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
094 would need a jump destination. If we then throw in a
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
102 construct with that
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
073 statement we get a complex implementation where we would have to keep track of optional jump destinations within
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
090 blocks and so on.

10.1 A Short Note on Exception Handling

With this basic understanding of the block stack, it is not difficult to fathom the implementation of exceptions and exception handling. Take the snippet in Listing 10.3 that tries to add a number to a string.

Listing 10.3: Simple python function with exception handling

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
1

Listing 10.4 shows the opcodes generated from this simple function.

Listing 10.4: Disassembly of function in listing 10.3

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
2

We should have a conceptual idea of how this code block will execute if an exception should occur given the previous explanation. In summary, we expect the

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
29 function from the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
106 module to return a
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
89 for the
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
22 opcode. In addition to returning a
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
89 value, the function also sets exception values on the currently executing thread’s thread state. Recall, that the thread state has the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
110,
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
111 and
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
112 fields for holding the current exception in the thread of execution; these fields prove very useful while unwinding the block stack in search of exception handlers. You can follow the chain of function calls from the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
113 function in the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
106 module all the way to the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
115 and
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
116 functions in the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
117 module where the exception gets set on the thread state.

With the exception values set on the currently executing thread’s thread state and a

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
89 value returned from the function call, the interpreter loop executes a jump to the error label where all the magic of exception handling occurs or not. For our trivial example above, we have only one block on the block stack, the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
119 block with a handler at bytecode offset 14. The stack unwinding begins after the jump to error handler label. The exception values - traceback, exception value and exception type, are pushed on top of the value stack, the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
119 handler gets popped from the block stack, and then there is a jump to the handler - byte offset 14 in this case where the execution continues. Observe the bytecodes from offset 16 to offset 20 in listing 10.4; here the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
121 class is loaded onto the stack, and then compared with the raised exception value present on the stack. If the exceptions match then normal execution can continue with the popping of exception and tracebacks from value stack and execution of any of the error handler code. When there is no exception match, the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
097 instruction is executed, and since there is still an exception on the stack, there is a break from the exception loop.

Trong trường hợp không có cơ chế xử lý ngoại lệ, các mã hóa cho hàm

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
89 đơn giản hơn như trong danh sách 10.5.

Liệt kê 10.5: Tháo chức năng trong danh sách 10.3 khi không có xử lý ngoại lệ

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
3

Các opcodes không đặt bất kỳ giá trị nào trên ngăn xếp khối, vì vậy khi một ngoại lệ theo sau là một bước nhảy vào nhãn xử lý lỗi xảy ra người sử dụng.

Mặc dù một số chi tiết thực hiện bị bỏ qua, chương này bao gồm các nguyên tắc cơ bản của sự tương tác giữa ngăn xếp khối và xử lý lỗi trong máy ảo Python. Có những chi tiết khác như xử lý ngoại lệ trong các ngoại lệ, trình xử lý ngoại lệ lồng nhau, v.v. Tuy nhiên, chúng tôi kết thúc Intermezzo ngắn này vào thời điểm này.

11. Từ mã lớp đến mã byteFrom Class code to bytecode

Chúng tôi đã bao gồm rất nhiều mặt đất thảo luận về các loại hạt và bu lông về cách máy ảo hoặc trình thông dịch của Python (cho dù bạn muốn gọi nó) - Các đai ốc và bu lông của cách một lớp do người dùng xác định được biên dịch xuống mã byte và được thực thi.

Các cuộc thảo luận của chúng tôi về các đối tượng Python đã cung cấp cho chúng tôi một ý tưởng sơ bộ về cách tạo ra các lớp mới; Tuy nhiên, trực giác này có thể không hoàn toàn nắm bắt toàn bộ quá trình từ thời điểm người dùng xác định

 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
51 trong nguồn cho mã byte do biên dịch lớp đó. Chương này nhằm mục đích thu hẹp khoảng cách đó và cung cấp một giải trình về quá trình này.

Như thường lệ, chúng tôi bắt đầu với danh sách lớp do người dùng định nghĩa đơn giản 11.0.

Liệt kê 11.0: Một định nghĩa lớp đơn giản

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
4

Liệt kê 11.1 là sự tháo gỡ của lớp trong danh sách 11.0.

Liệt kê 11.1: Một định nghĩa lớp đơn giản

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
5

Chúng tôi quan tâm đến các byte 0 đến 12, các mã thực tế tạo ra đối tượng lớp mới và lưu trữ nó để tham khảo trong tương lai bằng tên của nó (người trong ví dụ của chúng tôi). Trước đây, chúng tôi mở rộng trên các opcodes ở trên; Chúng tôi xem xét quá trình tạo lớp theo quy định của tài liệu Python. Mô tả của quá trình trong tài liệu, mặc dù được thực hiện ở mức rất cao, là khá đơn giản. Chúng tôi suy ra từ tài liệu Python rằng quá trình tạo lớp liên quan đến các bước sau.

  1. Cơ thể của câu lệnh lớp được phân lập thành một đối tượng mã.
  2. Các metaclass thích hợp để khởi tạo lớp được xác định.
  3. Một từ điển lớp đại diện cho không gian tên cho lớp được chuẩn bị.
  4. Đối tượng mã đại diện cho cơ thể lớp lớp được thực thi trong không gian tên này.
  5. Đối tượng lớp được tạo.

Trong bước cuối cùng, đối tượng lớp được tạo bằng cách khởi tạo lớp

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04, chuyển trong tên lớp, lớp cơ sở và từ điển lớp làm đối số. Bất kỳ móc
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
126 nào cũng được chạy trước khi khởi tạo đối tượng lớp. Metaclass được sử dụng trong việc tạo đối tượng lớp có thể được chỉ định rõ ràng bằng cách cung cấp đối số từ khóa
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
127 trong định nghĩa
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
51. Nếu không được cung cấp
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
127, trình thông dịch sẽ kiểm tra mục đầu tiên trong bộ phận của bất kỳ lớp cơ sở nào. Nếu các lớp cơ sở không được sử dụng, trình thông dịch tìm kiếm biến toàn cầu
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
130 và nếu không tìm thấy, Python sử dụng meta-class mặc định.

Toàn bộ quá trình tạo lớp bắt đầu với tải hàm

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
131 lên ngăn xếp giá trị. Chức năng này chịu trách nhiệm cho tất cả các loại nâng vật nặng tạo ra. Tiếp theo, đối tượng mã cơ thể loại, đã được biên dịch thành một đối tượng mã, được tải trên ngăn xếp theo lệnh tại Offset 2 -
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
11. Đối tượng mã này sau đó được gói vào một đối tượng hàm bởi opcode
1 >>> import ast
2 >>> import pprint
3 >>> node = ast.parse(code_str, mode="exec")
4 >>> ast.dump(node)
5 ("Module(body=[FunctionDef(name='hello_world', args=arguments(args=[], "
6 'vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), '
7 "body=[Return(value=Str(s='hello world'))], decorator_list=[], "
8 'returns=None)])')
72 và được đặt trở lại trên ngăn xếp; Nó sẽ sớm trở nên rõ ràng tại sao điều này xảy ra. Bằng cách bù 10; Ngăn xếp đánh giá trông tương tự như trong Hình 11.0.

Hướng dẫn does python use a virtual machine - python có sử dụng máy ảo không
Hình 11.0: Ngân hàng trạng thái đánh giá ngay trước
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
97

Ở độ bù 10,

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
97 xử lý gọi hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
136 với hai giá trị trên nó trên ngăn xếp đánh giá là đối số (đối số với
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
97 là hai). Hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
136 trong mô -đun
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
51 là công việc tạo ra lớp của chúng tôi. Một phần quan trọng của hàm được dành cho kiểm tra độ tỉnh - kiểm tra các đối số đúng, kiểm tra loại chính xác, v.v. Sau khi kiểm tra sự tỉnh táo này, chức năng sau đó phải quyết định đúng metaclass. Các quy tắc để xác định chính xác
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
127 được sao chép nguyên văn từ tài liệu Python.

  1. Nếu không có cơ sở và không có metaclass rõ ràng được đưa ra, thì
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    141 được sử dụng
  2. Nếu một metaclass rõ ràng được đưa ra và nó không phải là một ví dụ của
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    141, thì nó được sử dụng trực tiếp làm metaclass
  3. Nếu một thể hiện của loại () được đưa ra dưới dạng metaclass rõ ràng hoặc cơ sở được xác định, thì metaclass có nguồn gốc nhiều nhất được sử dụng

Metaclass xuất phát nhất được chọn từ metaclass được chỉ định rõ ràng (nếu có) và các metaclass (tức là

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
143) của tất cả các lớp cơ sở được chỉ định. Metaclass có nguồn gốc nhất là một loại phụ của tất cả các metaclass ứng cử viên này. Nếu không có ứng cử viên nào đáp ứng tiêu chí đó, thì định nghĩa lớp sẽ thất bại với
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
144.

Đoạn trích thực tế từ hàm

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
131 xử lý độ phân giải Metaclass nằm trong liệt kê 11.2, và nó đã được chú thích thêm một chút để cung cấp rõ ràng hơn.

Liệt kê 11.2: Một định nghĩa lớp đơn giản

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
6

Với metaclass được tìm thấy,

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
131 sau đó tiến hành kiểm tra xem có bất kỳ thuộc tính
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
126 nào có tồn tại trên metaclass hay không; Nếu bất kỳ thuộc tính nào như vậy tồn tại, không gian tên lớp được chuẩn bị bằng cách thực thi hook
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
126 vượt qua tên lớp, cơ sở lớp và bất kỳ đối số từ khóa bổ sung nào từ định nghĩa lớp. Móc này được sử dụng để tùy chỉnh hành vi của lớp. Ví dụ sau trong Liệt kê 11.3 được lấy từ ví dụ về định nghĩa Metaclass và sử dụng tài liệu Python cho thấy một ví dụ về cách sử dụng móc
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
126 để thực hiện một lớp với thứ tự thuộc tính.

Liệt kê 11.3: Một định nghĩa meta đơn giản

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
7

Hàm

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
131 trả về một
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
43 mới trống nếu không có thuộc tính
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
126 được xác định trên metaclass nhưng nếu có, không gian tên được sử dụng là kết quả của việc thực thi thuộc tính
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
126 như đoạn trích liệt kê 11.4.

Liệt kê 11.4: Chuẩn bị cho một lớp học mới

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
8

Sau khi xử lý móc

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
126, giờ đây đã đến lúc đối tượng lớp thực tế được tạo. Đầu tiên, việc thực hiện đối tượng mã cơ thể lớp xảy ra trong không gian tên từ đoạn trước. Để hiểu lý do tại sao hãy xem mã byte đối tượng mã này trong danh sách 11,5.

Liệt kê 11,5: Tháo gỡ đối tượng mã cho cơ thể lớp từ Liệt kê 11.0

1 def fizzbuzz(n):
2     if n % 3 == 0 and n % 5 == 0:
3         return 'FizzBuzz'
4     elif n % 3 == 0:
5         return 'Fizz'
6     elif n % 5 == 0:
7         return 'Buzz'
8     else:
9         return str(n)
9

Sau khi thực thi đối tượng mã này, không gian tên sẽ chứa tất cả các thuộc tính của lớp, tức là các thuộc tính, phương thức của lớp, v.v ... Không gian tên này sau đó được sử dụng như một đối số cho lệnh gọi hàm đến metaclass như trong liệt kê 11.6.

Liệt kê 11.6: Gọi một Metaclass để tạo một thể hiện lớp mới

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
00

Giả sử chúng tôi đang sử dụng metaclass

 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
04, gọi loại có nghĩa là phân tích thuộc tính trong khe
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
14 của lớp. Hàm
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
14 sau đó, lần lượt, đặt ra thuộc tính trong khe
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
23 tạo và trả về đối tượng lớp hoàn toàn mới của chúng tôi. Giá trị
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
159 được trả về sau đó được đặt trở lại trên ngăn xếp và được lưu trữ cho biến
 1 Init the indent stack with the value 0.
 2 For each logical line taking into consideration line-joining:
 3     A.  If the current line's indentation is greater than the 
 4     indentation at the top of the stack
 5         1.  Add the current line's indentation to the top of the stack.
 6         2.  Generate an INDENT token.
 7     B.  If the current line's indentation is less than the indentation
 8         at the top of the stack
 9         1. If there is no indentation level on the stack that matches the current li\
10 ne's indentation, report an error.
11         2.  For each value at the top of the stack, that is unequal to the current l\
12 ine's indentation.
13             a.  Remove the value from the top of the stack.
14             b.  Generate a DEDENT token.
15     C.  Tokenize the current line.
16 For every indentation on the stack except 0, produce a DEDENT token.
39. Ở đó chúng tôi có nó, quá trình tạo ra một lớp mới và đây là tất cả những gì có trong Python.

12. Máy phát điện: Đằng sau hậu trường.Generators: Behind the scenes.

Máy phát điện là một trong những khái niệm đẹp trong Python. Hàm trình tạo là một hàm chứa câu lệnh

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
161 và khi được gọi, nó trả về một trình tạo. Việc sử dụng đơn giản các máy phát điện trong Python là một trình lặp lại tạo ra các giá trị cho một lần lặp theo yêu cầu. Liệt kê 12.0 là một ví dụ đơn giản về chức năng tạo ra các giá trị từ
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
64 cho đến
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
163.

Liệt kê 12.0: một máy phát đơn giản

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
01

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
164 chứa câu lệnh
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
161, do đó, gọi nó sẽ không trả về một giá trị đơn giản như một hàm thông thường sẽ làm. Thay vào đó, nó sẽ trả về một đối tượng Trình tạo nắm bắt sự tiếp tục của tính toán. Sau đó, chúng ta có thể sử dụng hàm
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
68 để nhận các giá trị liên tiếp từ đối tượng Trình tạo được trả về hoặc gửi các giá trị vào trình tạo bằng phương thức
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
167 của đối tượng Trình tạo.continuation of the computation. We can then use the
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
68 function to get successive values from the returned generator object or send values into the generator using the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
167 method of the generator object.

Trong chương này, chúng tôi không quan tâm đến ngữ nghĩa của các đối tượng máy phát điện hoặc cách sử dụng chúng đúng. Sự quan tâm của chúng tôi là cách các máy phát điện được thực hiện theo các bìa trong CPython. Chúng tôi quan tâm đến cách có thể đình chỉ tính toán và sau đó tiếp tục tính toán đó. Chúng tôi nhìn vào các cấu trúc dữ liệu và ý tưởng đằng sau khái niệm này, và thật đáng ngạc nhiên, chúng không quá phức tạp. Đầu tiên, chúng tôi xem xét việc triển khai C của một đối tượng máy phát.

12.1 Đối tượng Trình tạoThe Generator object

Liệt kê 12.1 là định nghĩa của một đối tượng Trình tạo và trải qua định nghĩa này cung cấp một số trực giác về cách thực thi trình tạo có thể bị đình chỉ hoặc nối lại. Chúng ta có thể thấy rằng một đối tượng Trình tạo chứa một đối tượng khung và đối tượng mã, hai đối tượng cần thiết cho việc thực thi mã byte Python.

Liệt kê 12.1: Định nghĩa đối tượng máy phát điện

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
02

Sau đây bao gồm các thuộc tính chính của đối tượng Trình tạo.

  1.  1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    168: Trường này tham chiếu một đối tượng khung. Đối tượng khung này chứa đối tượng mã của trình tạo và trong khung này, việc thực hiện đối tượng mã của đối tượng Trình tạo diễn ra.
  2.  1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    169: Đây là trường boolean cho biết liệu trình tạo có đang chạy hay không.
  3.  1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    170: Trường này tham chiếu đối tượng mã được liên kết với trình tạo. Đây là đối tượng mã thực thi bất cứ khi nào trình tạo đang chạy.
  4.  1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    171: Đây là tên của trình tạo - trong danh sách 12.0, giá trị là
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    164.
  5.  1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    173: Đây là tên đủ điều kiện của trình tạo. Hầu hết các lần giá trị này giống như của
     1     typedef struct _ts {
     2         struct _ts *prev;
     3         struct _ts *next;
     4         PyInterpreterState *interp;
     5 
     6         struct _frame *frame;
     7         int recursion_depth;
     8         char overflowed; 
     9                         
    10         char recursion_critical; 
    11         int tracing;
    12         int use_tracing;
    13 
    14         Py_tracefunc c_profilefunc;
    15         Py_tracefunc c_tracefunc;
    16         PyObject *c_profileobj;
    17         PyObject *c_traceobj;
    18 
    19         PyObject *curexc_type;
    20         PyObject *curexc_value;
    21         PyObject *curexc_traceback;
    22 
    23         PyObject *exc_type;
    24         PyObject *exc_value;
    25         PyObject *exc_traceback;
    26 
    27         PyObject *dict;  /* Stores per-thread state */
    28         int gilstate_counter;
    29 
    30         ... 
    31     } PyThreadState;
    
    171.

Tạo máy phát điện

Khi chúng ta gọi hàm Trình tạo, hàm Trình tạo không chạy để hoàn thành và trả về giá trị; Thay vào đó, nó tạo ra một đối tượng máy phát. Điều này là do cờ

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
175 được đặt khi biên dịch hàm máy phát. Cờ này rất hữu ích trong quá trình thiết lập xảy ra ngay trước khi thực thi đối tượng mã.

Trong quá trình thực thi đối tượng mã cho hàm, hãy nhớ lại

 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 được gọi để thực hiện một số thiết lập. Trong quá trình thiết lập này, trình thông dịch kiểm tra xem cờ
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
175; Nếu được đặt, nó sẽ tạo và trả về một đối tượng Trình tạo thay vì gọi chức năng vòng lặp đánh giá. Phép thuật xảy ra tại khối mã cuối cùng của
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87 như trong danh sách 12.2.

Liệt kê 12.2: _PyEVAL_EVALCODEWITHNAME Trả về một đối tượng Trình tạo khi xử lý một đối tượng mã với cờ máy phát điện

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
03

Chúng ta có thể thấy từ Liệt kê 12.2 mã byte cho một đối tượng mã chức năng trình tạo không bao giờ được thực thi tại điểm của lệnh gọi hàm - việc thực thi mã byte chỉ xảy ra khi đối tượng Trình tạo được trả về đang chạy và chúng ta xem xét điều này tiếp theo.

12.2 Chạy máy phát điệnRunning a generator

Chúng ta có thể chạy một đối tượng Trình tạo bằng cách chuyển nó như một đối số cho hàm tích hợp

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
68. Điều này sẽ khiến trình tạo thực thi cho đến khi nó đạt biểu thức
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
161 sau đó nó đình chỉ thực thi. Câu hỏi quan trọng ở đây là làm thế nào các trình tạo có thể nắm bắt trạng thái thực thi và cập nhật những người theo ý muốn.

Nhìn lại định nghĩa đối tượng của Trình tạo Trong danh sách 12.1, chúng ta thấy rằng các trình tạo có một trường tham chiếu một đối tượng khung và điều này được điền khi trình tạo được tạo như trong danh sách 12.2. Đối tượng khung như chúng ta nhớ lại có tất cả các trạng thái được yêu cầu để thực thi một đối tượng mã để có tham chiếu đến khung thực thi đó, đối tượng Trình tạo có thể nắm bắt tất cả trạng thái cần thiết để thực thi.

Bây giờ chúng ta biết làm thế nào một đối tượng máy phát nắm bắt trạng thái thực thi, chúng ta chuyển sang câu hỏi làm thế nào việc thực hiện đối tượng Trình tạo lơ lửng được nối lại và điều này không quá khó để tìm ra thông tin mà chúng ta đã có. Khi hàm tích hợp

 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
68 được gọi với trình tạo làm đối số, hàm
 1 	>>> from dis import dis
 2         >>> def square(x):
 3         ...     return x*x
 4         ... 
 5 
 6         >>> dis(square)
 7         2           0 LOAD_FAST                0 (x)
 8                     2 LOAD_FAST                0 (x)
 9                     4 BINARY_MULTIPLY     
10                     6 RETURN_VALUE        
68 sẽ đặt ra trường
 1 stmt: simple_stmt | compound_stmt
 2 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
 3 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
 4         import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
 5 expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
 6                 ('=' (yield_expr|testlist_star_expr))*)
 7 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
 8 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' 
 9         | '<<=' | '>>=' | '**=' | '//=')
10 
11 del_stmt: 'del' exprlist
12 pass_stmt: 'pass'
13 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
14         yield_stmt
15 break_stmt: 'break'
16 continue_stmt: 'continue'
17 return_stmt: 'return' [testlist]
18 yield_stmt: yield_expr
19 raise_stmt: 'raise' [test ['from' test]]
20 import_stmt: import_name | import_from
21 import_name: 'import' dotted_as_names
22 import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
23         'import' ('*' | '(' import_as_names ')' | import_as_names))
24 import_as_name: NAME ['as' NAME]
25 dotted_as_name: dotted_name ['as' NAME]
26 import_as_names: import_as_name (',' import_as_name)* [',']
27 dotted_as_names: dotted_as_name (',' dotted_as_name)*
28 dotted_name: NAME ('.' NAME)*
29 global_stmt: 'global' NAME (',' NAME)*
30 nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
31 assert_stmt: 'assert' test [',' test]
32 
33         ...
60 của loại trình tạo và gọi bất kỳ hàm nào tham chiếu trường. Trong trường hợp của một đối tượng Trình tạo, trường đó tham chiếu một hàm,
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
184, gọi hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
185, thực hiện công việc thực tế để tiếp tục thực hiện đối tượng Trình tạo. Trước khi đối tượng Trình tạo được tạo, thiết lập ban đầu của đối tượng khung và biến được thực hiện bởi hàm
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
87, do đó việc thực thi đối tượng Trình tạo liên quan đến việc gọi
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
83 với đối tượng khung có trong đối tượng Trình tạo làm đối số khung. Việc thực hiện đối tượng mã có trong khung sau đó được tiến hành như đã giải thích chương về vòng đánh giá.

Để có được cái nhìn sâu hơn về chức năng trình tạo, chúng tôi xem xét chức năng Trình tạo trong liệt kê 12.0. Việc tháo gỡ hàm máy phát trong liệt kê 12.0 kết quả trong tập hợp mã byte được hiển thị trong danh sách 12.3.

Liệt kê 12.3: Tháo gỡ chức năng của máy phát từ Liệt kê 12.0

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
04

Khi việc thực hiện mã byte được hiển thị trong liệt kê 12.3 cho hàm Trình tạo sẽ đến opcode

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
188 ở độ lệch byte 16, opcode đó khiến việc đánh giá bị đình chỉ và trả lại giá trị trên đầu ngăn xếp cho người gọi. Khi bị đình chỉ, chúng tôi có nghĩa là vòng lặp đánh giá cho khung hiện đang thực hiện được thoát tuy nhiên khung này không được giải quyết vì nó vẫn được tham chiếu bởi đối tượng Trình tạo để việc thực thi khung có thể tiếp tục khi
 1 static expr_ty
 2 ast_for_ifexpr(struct compiling *c, const node *n)
 3 {
 4     /* test: or_test 'if' or_test 'else' test */
 5     expr_ty expression, body, orelse;
 6 
 7     assert(NCH(n) == 5);
 8     body = ast_for_expr(c, CHILD(n, 0));
 9     if (!body)
10         return NULL;
11     expression = ast_for_expr(c, CHILD(n, 2));
12     if (!expression)
13         return NULL;
14     orelse = ast_for_expr(c, CHILD(n, 4));
15     if (!orelse)
16         return NULL;
17     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
18                  c->c_arena);
19 }
83 được gọi với khung tranh luận.

Các trình tạo Python làm nhiều hơn chỉ tạo ra các giá trị; Họ cũng có thể tiêu thụ các giá trị bằng cách sử dụng phương thức Trình tạo

 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
167. Điều này là có thể bởi vì
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
161 là một biểu thức đánh giá theo giá trị. Khi phương thức gửi được gọi trên một trình tạo có giá trị, phương thức
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
185 đặt giá trị lên ngăn xếp đánh giá của khung đối tượng máy phát trước khi đánh giá đối tượng khung lại. Liệt kê 12.3 cho thấy hướng dẫn
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
16 xuất hiện sau
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
188; Điều này lưu trữ giá trị ở đầu ngăn xếp đến tên được cung cấp. Trong trường hợp không có gọi hàm
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
167, thì giá trị không được đặt trên đỉnh của ngăn xếp.generate values; they can also consume values by using the generator
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
167 method. This is possible because
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
161 is an expression that evaluates to a value. When the send method is called on a generator with a value, the
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
185 method places the value onto the evaluation stack of the generator object frame before the evaluation of the frame object resumes. Listing 12.3 shows the
 1 stmt = FunctionDef(identifier name, arguments args,
 2                    stmt* body, expr* decorator_list, expr? returns)
 3       | AsyncFunctionDef(identifier name, arguments args,
 4                          stmt* body, expr* decorator_list, expr? returns)
 5 
 6       | ClassDef(identifier name,
 7          expr* bases,
 8          keyword* keywords,
 9          stmt* body,
10          expr* decorator_list)
11       | Return(expr? value)
12 
13       | Delete(expr* targets)
14       | Assign(expr* targets, expr value)
15       | AugAssign(expr target, operator op, expr value)
16       -- 'simple' indicates that we annotate simple name without parens
17       | AnnAssign(expr target, expr annotation, expr? value, int simple)
18 
19       -- use 'orelse' because else is a keyword in target languages
20       | For(expr target, expr iter, stmt* body, stmt* orelse)
21       | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
22       | While(expr test, stmt* body, stmt* orelse)
23       | If(expr test, stmt* body, stmt* orelse)
24       | With(withitem* items, stmt* body)
25       | AsyncWith(withitem* items, stmt* body)
16 instruction comes after
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
188; this stores the value at the top of the stack to the provided name. In the case where there is no
 1     typedef struct _ts {
 2         struct _ts *prev;
 3         struct _ts *next;
 4         PyInterpreterState *interp;
 5 
 6         struct _frame *frame;
 7         int recursion_depth;
 8         char overflowed; 
 9                         
10         char recursion_critical; 
11         int tracing;
12         int use_tracing;
13 
14         Py_tracefunc c_profilefunc;
15         Py_tracefunc c_tracefunc;
16         PyObject *c_profileobj;
17         PyObject *c_traceobj;
18 
19         PyObject *curexc_type;
20         PyObject *curexc_value;
21         PyObject *curexc_traceback;
22 
23         PyObject *exc_type;
24         PyObject *exc_value;
25         PyObject *exc_traceback;
26 
27         PyObject *dict;  /* Stores per-thread state */
28         int gilstate_counter;
29 
30         ... 
31     } PyThreadState;
167 function call, then the None value is placed on the top of the stack.

Ghi chú

Python có chạy một máy ảo không?

Python, giống như nhiều ngôn ngữ được giải thích, thực sự biên dịch mã nguồn cho một tập hợp các hướng dẫn cho một máy ảo và trình thông dịch Python là một triển khai của máy ảo đó.Định dạng trung gian này được gọi là "mã byte.", and the Python interpreter is an implementation of that virtual machine. This intermediate format is called "bytecode."

Ngôn ngữ nào sử dụng máy ảo?

Loại VM này đã trở nên phổ biến với ngôn ngữ lập trình Java, được triển khai bằng máy ảo Java.Các ví dụ khác bao gồm máy ảo vẹt và.Net Framework, chạy trên VM có tên là thời gian chạy ngôn ngữ chung.Java programming language, which is implemented using the Java virtual machine. Other examples include the Parrot virtual machine and the . NET Framework, which runs on a VM called the Common Language Runtime.

Python chạy trên gì?

Python là ngôn ngữ lập trình đa nền tảng, có nghĩa là nó có thể chạy trên nhiều nền tảng như Windows, MacOS, Linux và thậm chí đã được chuyển đến máy ảo Java và .NET.Nó là miễn phí và nguồn mở.Windows, macOS, Linux, and has even been ported to the Java and .NET virtual machines. It is free and open-source.