#28. Khung

Khung là bản ghi thời gian chạy cho một lần thực thi mã Python đang hoạt động. Khi CPython gọi một hàm Python, thực thi phần thân mô-đun, chạy phần thân lớp, tiếp tục trình tạo hoặc tiếp tục một coroutine, nó sẽ sử dụng bản ghi thực thi giống như khung để giữ trạng thái hiện tại.

Một đối tượng mã cho biết những gì cần thực thi.

Một khung cho biết vị trí thực thi hiện tại và giá trị nào hiện đang hoạt động.text code object = immutable instructions and metadata frame = mutable execution state for one run of that code Đối với chức năng này:```python def add(a, b): c = a + b return c


Mt khung được to cho`add(2, 3)`cha các giá tr đối s hin ti, các v trí biến cc b, giá tr ngăn xếp, v trí lnh, trng thái ngoi l và các liên kết đến bi cnh thc thi.

## 28.1 Tại sao khung tồn tại

Mt chương trình Python có th có nhiu lnh gi hot động cùng lúc:```python
def a():
    return b()

def b():
    return c()

def c():
    return 42

a()
```Trong quá trình thc thi, CPython cn ghi nh tng lnh gi b treo trong khi lnh gi chy.

V mt khái nim:```text
frame for a
    waiting for b

frame for b
    waiting for c

frame for c
    currently executing
```Mi khung lưu tr đủ trng thái để tiếp tc mã ca nó sau khi lnh gi lng nhau quay tr li.

Mt khung tr li nhng câu hi sau:```text
Which code object is running?
Which instruction is next?
What are the local variables?
What temporary values are on the stack?
Which globals and builtins are visible?
What exception is being handled?
Is tracing or profiling active?
Who called this frame?
```## 28.2 Đối tượng mã và khung

Mt đối tượng mã có th tái s dng được. Mt khung là mt trường hp thc thi.```python
def f(x):
    return x + 1

a = f(10)
b = f(20)
```C hai cuc gi đều s dng cùng mt đối tượng mã:```python
print(f.__code__)
```Nhưng mi cuc gi có trng thái khung riêng.

| Khái nim | Đối tượng mã | Khung |
|---|---|---|
| Kh năng thay đổi | Ch yếu là bt biến | Có th thay đổi |
| Trn đời | Thường tn ti lâu dài | Thông thường mt cuc gi hoc thc hin b đình ch |
| Cha mã byte | Có | Đối tượng mã tham chiếu |
| Cha người dân địa phương | Không | Có |
| Cha ngăn xếp | Không | Có |
| Cha con tr lnh | Không | Có |
| Được chia s qua các cuc gi | Có | Không |

Đối tượng mã là đon chương trình. Khung là quá trình kích hot đang chy ca đon đó.

## 28.3 Khung chức năng

Lnh gi hàm s to hoc khi to mt khung cho callee.```python
def square(x):
    return x * x

square(9)
```Đối tượng hàm cha:```text
code object
globals
defaults
keyword defaults
closure cells
annotations
qualname
module name
```Khi được gi, CPython kết hp đối tượng hàm vi các đối s thc tế và to trng thái thc thi khung.

V mt khái nim:```text
function object
    code object
    globals

call arguments
    x = 9

new frame
    code = square.__code__
    globals = square.__globals__
    locals slot 0 = 9
    value stack = empty
    instruction pointer = start
```Sau đó, vòng đánh giá s chy khung cho đến khi nó tr v, tăng, nhường hoc tm dng.

## 28.4 Khung mô-đun

Phn thân mô-đun cũng được thc thi trong mt khung.

Đối vi mt tp tin:```python
# app.py
x = 10

def f():
    return x
```CPython biên dch toàn b mô-đun thành mt đối tượng mã. Vic chy tp s thc thi đối tượng mã đó trong không gian tên mô-đun.

V mt khái nim:```text
module frame
    code = compiled app.py
    globals = module.__dict__
    locals = module.__dict__
``` phm vi mô-đun, toàn cu và địa phương thường tham chiếu đến cùng mt t đin.

Đây là lý do ti sao phép gán cp cao nht được ghi vào không gian tên mô-đun:```python
x = 10
```to ra:```text
module.__dict__["x"] = 10
```Vic thc thi chc năng là khác nhau. Chc năng cc b s dng các khe cc b nhanh ch không phi t đin mô-đun làm b lưu tr chính.

## Khung thân lớp 28.5

Thân lp cũng thc thi dưới dng mã.```python
class User:
    kind = "human"

    def name(self):
        return "anonymous"
```Câu lnh lp không ch đơn gin khai báo mt cu trúc tĩnh. CPython thc thi phn thân lp trong mt không gian tên tm thi, sau đó xây dng đối tượng lp t không gian tên đó.

V mt khái nim:```text
prepare class namespace
execute class body frame
collect assignments and function objects
call metaclass to create class object
bind class object to name User
```Trong quá trình thc thi ni dung lp:```python
kind = "human"
```lưu tr vào không gian tên lp.

Hàm lng nhau:```python
def name(self):
    return "anonymous"
```to mt đối tượng hàm và lưu tr nó trong không gian tên lp. Nó không chy phn thân phương thc.

Sau khi ni dung lp kết thúc, CPython chuyn không gian tên cho siêu d liu, thường là`type`.

## 28.6 Nội dung khung

Bn ghi thc thi ging khung CPython cha mt s loi d liu.

| Danh mc | Mc đích |
|---|---|
| Mã tham kho | Đối tượng mã đang được thc thi |
| Toàn cu | Không gian tên toàn cu để tra cu tên |
| Ni dung | D phòng không gian tên dng sn |
| Người dân địa phương | Biến cc b hoc không gian tên |
| Người dân địa phương nhanh chóng | Mng khe cho hàm cc b |
| Ngăn xếp giá tr | Toán hng tm thi cho mã byte |
| Trng thái hướng dn | V trí mã byte hin ti |
| Trng thái ngoi l | Siêu d liu x lý ngoi l đang hot động |
| Quan h người gi | Liên kết ti khung trước đó hoc ng cnh cuc gi |
| Trng thái truy tìm | Trình g li, trình lược t, móc bo him |
| Nhà nước ch s hu | Trình to, coroutine hoc trng thái cuc gi thông thường |

Mt cu trúc đơn gin hóa trông như thế này:```text
frame
    code object
    previous frame
    globals dictionary
    builtins dictionary
    locals representation
    fast local slots
    value stack
    instruction pointer
    exception state
    tracing flags
```Cu trúc C chính xác thay đổi trên các phiên bn CPython. Các trường khái nim vn n định.

## 28.7 Người dân địa phương nhanh

Chc năng cc b được ti ưu hóa.

Trong chc năng này:```python
def f(a, b):
    c = a + b
    return c
```Trình biên dch biết tên địa phương:```text
a
b
c
```Nó gán cho chúng các ch mc:

| Tên | Khe |
|---|---:|
|`a`| 0 |
|`b`| 1 |
|`c`| 2 |

Trong quá trình thc thi, CPython có th truy cp cc b theo v trí:```text
LOAD_FAST 0
LOAD_FAST 1
STORE_FAST 2
LOAD_FAST 2
```Điu này tránh vic tra cu t đin cho các hàm cc b thông thường.

Khung lưu tr các giá tr này trong mt vùng ging như mng:```text
fast locals
    slot 0: a
    slot 1: b
    slot 2: c
```Đây là mt lý do khiến biến cc b nhanh hơn biến toàn cu.

## 28.8 Từ điển địa phương

Python gii thiu người dân địa phương thông qua`locals()`và thuc tính khung.```python
def f(a):
    b = a + 1
    print(locals())

f(10)
```Đầu ra:```text
{'a': 10, 'b': 11}
```Nhưng bên trong mt hàm, b lưu tr thc thi thc tế là cc b nhanh. Chế độ xem t đin có th được c th hóa hoc đồng b hóa vi b nh trong tùy thuc vào ng cnh và phiên bn Python.

S khác bit này rt quan trng:```python
def f():
    x = 1
    locals()["x"] = 2
    return x
```Bn không nên da vào vic sa đổi t đin được tr v bi`locals()`để thay đổi các biến cc b được ti ưu hóa bên trong mt hàm.

 phm vi mô-đun, tình hung khác:```python
locals()["x"] = 2
print(x)
``` cp độ mô-đun, người dân địa phương là t đin mô-đun, vì vy điu này thường hot động.

## 28.9 Toàn cầu và Nội dung

Mt khung lưu tr các tham chiếu đến các không gian tên chung và ni trang được s dng để phân gii tên.

Vì:```python
def f(xs):
    return len(xs)

lenkhông phải là biến cục bộ. CPython sử dụng tra cứu toàn cầu:text look in function globals if missing, look in builtins if missing, raise NameError Khung cung cấp cả hai từ điển:text frame.globals = module namespace frame.builtins = builtins namespace Về mặt khái niệm:python def f(xs): return len(xs) chạy như:```text LOAD_GLOBAL len LOAD_FAST xs CALL 1 RETURN_VALUE


`LOAD_GLOBAL`ph thuc vào toàn cu và ni dung ca khung.

## 28.10 Ngăn xếp giá trị

Mi khung có mt ngăn xếp giá tr được s dng để thc thi mã byte.

Vì:```python
def f(a, b, c):
    return (a + b) * c
```Ngăn xếp thay đổi gn như thế này:

| Hướng dn | Xếp chng trước | Xếp chng sau |
|---|---|---|
|`LOAD_FAST a` | `[]` | `[a]` |
| `LOAD_FAST b` | `[a]` | `[a, b]` |
| `BINARY_OP +` | `[a, b]` | `[a + b]` |
| `LOAD_FAST c` | `[a + b]` | `[a + b, c]` |
| `BINARY_OP *` | `[a + b, c]` | `[(a + b) * c]` |
| `RETURN_VALUE` | `[result]`| tr li |

Ngăn xếp lưu tr các tham chiếu đối tượng, không phi các giá tr thô chưa được đóng hp.

Vì vy, đối vi s nguyên, ngăn xếp cha các con tr ti các đối tượng s nguyên Python.```text
value stack
    PyObject* -> int object
    PyObject* -> int object
```Hướng dn mã byte đẩy, bt, thay thế hoc kim tra các mc nhp ngăn xếp này.

## 28.11 Vị trí hướng dẫn

Mt khung theo dõi v trí mã byte hin ti.

Đối vi mã đường thng, con tr lnh tiến lên.

Đối vi các nhánh, nó nhy.```python
def abs_like(x):
    if x < 0:
        return -x
    return x
```Lung điu khin khái nim:```text
load x
load 0
compare <
jump if false to return_x
load x
unary negative
return
return_x:
load x
return
```Khung ghi li hướng dn tiếp theo. V trí này quan trng đối vi:```text
normal execution
branches
loops
exceptions
tracebacks
line tracing
profiling
debugging
```Tracebacks s dng trng thái khung để báo cáo nơi xy ra ngoi l.

## 28.12 Khung và dấu vết

Khi mt ngoi l lan truyn, CPython ghi li thông tin truy nguyên t các khung.

Ví d:```python
def a():
    b()

def b():
    c()

def c():
    1 / 0

a()
```Truy nguyên hin th chui cuc gi đang hot động:```text
a
b
c
ZeroDivisionError
```Mi mc truy ngược đề cp đến mt khung và v trí lnh. Đây là lý do ti sao Python có th hin th tên tp ngun, s dòng và tên hàm.

Truy nguyên không ch đơn thun là mt chui. Nó là mt chui thông tin thi gian chy có cu trúc.

## 28.13 Truy cập khung từ Python

Python hin th các đối tượng khung thông qua mt s API.```python
import inspect

def f():
    frame = inspect.currentframe()
    print(frame.f_code.co_name)
    print(frame.f_locals)
    print(frame.f_globals is globals())

f()
```các`frame`đối tượng hin th các trường như:

| Thuc tính | Ý nghĩa |
|---|---|
|`f_code`| Đối tượng mã |
|`f_locals`| Chế độ xem không gian tên cc b |
|`f_globals`| Không gian tên toàn cu |
|`f_builtins`| Không gian tên dng sn |
|`f_back`| Khung trước |
|`f_lineno`| Dòng ngun hin ti |
|`f_trace`| Chc năng theo dõi |

Bn cũng có th s dng:```python
import sys

frame = sys._getframe()
print(frame.f_code.co_name)
```Các API này mnh m nhưng nhy cm vi vic trin khai. Gi cho các đối tượng khung còn tn ti cũng có th gi cho các biến và đối tượng cc b còn tn ti.

## 28.14 Thời gian sử dụng khung hình

Hu hết các khung chc năng bình thường đều tn ti trong thi gian ngn.```python
def f():
    x = object()
    return 1

f()
```Khi`f`tr v, khung ca nó có th b hy hoc tái s dng và các tham chiếu cc b ca nó có th được gii phóng.

Nhưng khung có th tn ti lâu hơn trong mt s trường hp:```text
tracebacks keep frames alive
generators suspend frames
coroutines suspend frames
debuggers inspect frames
profilers observe frames
closures may keep cells alive
manual references to frames keep them alive
```Ví d:```python
import inspect

saved = None

def f():
    global saved
    x = [1, 2, 3]
    saved = inspect.currentframe()

f()
```Toàn cu`saved`bây gi đề cp đến khung. Khung đó đề cp đến người dân địa phương ca nó. Danh sách được giao cho`x`có th vn còn sng vì khung vn còn sng.

Đây là nguyên nhân ph biến gây ra tình trng lưu gi b nh đáng ngc nhiên trong các công c g li và mã x lý ngoi l.

## 28.15 Chuỗi khung

Mt khung có th tham chiếu người gi nó thông qua`f_back`.

```python
import inspect

def outer():
    inner()

def inner():
    frame = inspect.currentframe()
    print(frame.f_code.co_name)
    print(frame.f_back.f_code.co_name)

outer()
```V mt khái nim:```text
inner frame
    f_back -> outer frame
        f_back -> module frame
```Chui này cho phép xây dng truy nguyên và kim tra ngăn xếp.

Điu đó cũng có nghĩa là vic gi khung trong cùng có th gi cho khung ca người gi tn ti.```text
saved inner frame
    keeps outer frame
        keeps module frame references
```Đối vi các công c nhy cm vi b nh, các tham chiếu khung phi được gii phóng mt cách có ch ý.

## 28.16 Trình tạo và Khung treo

Trình to gi trng thái thc thi sau khi đạt năng sut.```python
def gen():
    x = 1
    yield x
    x = 2
    yield x
```Gi hàm s to mt đối tượng trình to:```python
g = gen()
```Cơ th không chy ngay lp tc. Khi được tiếp tc:```python
next(g)
```khung hình chy cho đến ln đầu tiên`yield`.

Sau đó`yield`, khung vn b treo:```text
generator object
    suspended frame
        code object
        local x = 1
        instruction position after first yield
        value stack state
```Cuc gi tiếp theo s tiếp tc t v trí hướng dn đã lưu đó:```python
next(g)
```Điu này khác vi khung chc năng thông thường, kết thúc khi tr v.

## 28.17 Coroutine và Frame

Coroutine s dng ý tưởng chung ging như trình to: trng thái thc thi có th tiếp tc.```python
async def fetch():
    data = await read()
    return data
```Ti`await`, coroutine có th tm dng. Khung ca nó gi li:```text
local variables
current instruction position
pending awaitable
exception state
return path
```Mt vòng lp s kin sau đó s tiếp tc li nó.```text
coroutine object
    suspended frame or frame-like state
        locals
        stack
        instruction pointer
```Do đó, vic thc thi không đồng b ph thuc vào vic tm dng và ni li khung. Nó không phi là thi gian chy ngôn ng riêng bit.

## 28.18 Vật chất hóa khung

CPython hin đại phân bit các khung thc thi ni b vi các đối tượng khung hin th đầy đủ bng Python.

Trình thông dch có th chy vi các khung bên trong nh gn để đạt hiu sut cao. Mt đối tượng khung hình đầy đủ ch có th được to khi cn bng cách xem xét ni tâm, theo dõi, g li, x lý truy nguyên hoc các API như`sys._getframe()`.

V mt khái nim:```text
internal frame
    optimized execution record

Python frame object
    object exposed to Python code
    wraps or materializes execution state
```S khác bit này ci thin hiu sut vì không phi mi lnh gi hàm đều cn mt đối tượng khung Python được phân b theo đống mà mã người dùng có th nhìn thy.

Mô hình khái nim vn gi nguyên: vn có trng thái thc thi. S đại din chính xác có th khác nhau.

## 28.19 Khung và Đóng

Vic đóng ca yêu cu b nh đặc bit cho các biến được chia s gia các hàm lng nhau.

Ví d:```python
def outer():
    x = 10

    def inner():
        return x

    return inner
```Biến`x`phi sng sót sau`outer`tr v vì`inner`vn s dng nó.

CPython x lý vic này bng các đối tượng ô.

V mt khái nim:```text
outer frame
    x stored in cell

inner function
    closure references same cell
```Sau đó`outer`tr v, khung có th biến mt, nhưng ô vn tn ti vì hàm tr v tham chiếu đến nó.```python
fn = outer()
print(fn())
```Vic đóng ca không gi được toàn b`outer`frame còn sng trong trường hp bình thường. Nó gi cho các biến ô cn thiết còn tn ti.

## 28.20 Biến ô và biến miễn phí

Trình biên dch phân loi các biến đóng.

| K hn | Ý nghĩa |
|---|---|
| Biến ô | Biến cc b được nm bt bi hàm bên trong |
| Biến min phí | Biến được s dng  đây nhưng được xác định  phm vi bên ngoài |

Ví d:```python
def outer():
    x = 1

    def inner():
        return x

    return inner
```Vì`outer`, `x`là mt biến ô.

Vì`inner`, `x`là mt biến t do.

Bn có th kim tra điu này:```python
def outer():
    x = 1
    def inner():
        return x
    return inner

print(outer.__code__.co_cellvars)
print(outer().__code__.co_freevars)
```B cc khung bao gm b nh cho các ô này để các hàm lng nhau có th chia s các biến mt cách an toàn.

## 28.21 Khung và Ngoại lệ

Khung lưu tr trng thái x lý ngoi l.

Vì:```python
def f(x):
    try:
        return 10 / x
    except ZeroDivisionError:
        return 0
```Đối tượng mã cha siêu d liu x lý ngoi l. Khung lưu tr trng thái thc thi hin ti cn thiết để s dng siêu d liu đó.

Khi phép chia đưa ra mt ngoi l, trình thông dch s s dng v trí hướng dn ca khung để tìm trình x lý phù hp.

V mt khái nim:```text
exception raised
    inspect current frame
    locate handler for current bytecode range
    adjust stack state
    jump to handler
```Nếu không có trình x lý nào tn ti trong khung hin ti, khung s thư giãn và ngoi l s truyn đến khung người gi.

## 28.22 Khung và`finally`MỘT`finally`khối cũng phụ thuộc vào trạng thái khung chính xác.```python
def f():
    try:
        return 1
    finally:
        cleanup()
```các`finally`khi chy ngay c khi hàm đang quay tr li.

Khung phi nh rng lnh tr v đang ch x lý trong khi nó thc thi mã dn dp.

V mt khái nim:```text
start return with value 1
enter finally block
call cleanup
if cleanup succeeds:
    complete original return
if cleanup raises:
    replace return with new exception
```Đây là lý do ti sao trng thái ngoi l và tr v là mt phn ca quá trình thc thi khung ch không phi là nhng suy nghĩ đơn gin.

## 28.23 Khung và Truy tìm

Móc truy tìm hot động trên khung.```python
import sys

def trace(frame, event, arg):
    print(event, frame.f_code.co_name, frame.f_lineno)
    return trace

def f(x):
    y = x + 1
    return y

sys.settrace(trace)
f(10)
sys.settrace(None)
```Hàm theo dõi nhn khung hin ti. Nó có th kim tra mã, địa phương, toàn cu, s dòng và mi quan h cuc gi.

Vic theo dõi rt hu ích cho:```text
debuggers
coverage tools
teaching tools
profilers
runtime monitors
```Nhưng vic truy tìm có cái giá phi tr. Nó buc trình thông dch phi duy trì và hin th nhiu trng thái hơn ti nhiu đim thc thi hơn.

## 28.24 Khung và Cấu hình

H sơ tương t nhưng thường thô hơn so vi truy tìm.```python
import sys

def profile(frame, event, arg):
    print(event, frame.f_code.co_name)

sys.setprofile(profile)

def f():
    return 1

f()
sys.setprofile(None)
```Các s kin lp h sơ bao gm các cuc gi và tr li. Trình phân tích s dng d liu khung để phân b thi gian hoc s lượng cuc gi cho các hàm.

Khung cung cp ánh x t thc thi thi gian chy đến cu trúc chương trình cp ngun.

## 28.25 Khung và đệ quy

Cuc gi đệ quy to nhiu khung cho cùng mt đối tượng mã.```python
def fact(n):
    if n <= 1:
        return 1
    return n * fact(n - 1)
```Vì`fact(4)`:

```text
fact(4)
    fact(3)
        fact(2)
            fact(1)
```Mi cuc gi đều có địa phương riêng`n`.

```text
frame fact: n = 4
frame fact: n = 3
frame fact: n = 2
frame fact: n = 1
```Tt c các khung đều tham chiếu cùng mt đối tượng mã, nhưng các v trí cc b ca chúng khác nhau.

CPython theo dõi độ sâu đệ quy để ngăn các cuc gi đệ quy không gii hn làm cn kit tài nguyên cp thp hơn.

## 28.26 Khung hình và khả năng lưu giữ bộ nhớ

Khung có th gi li nhiu b nh hơn d kiến.

Ví d:```python
def load_big():
    data = bytearray(100_000_000)
    raise RuntimeError("failed")

try:
    load_big()
except RuntimeError as exc:
    saved = exc
```Ngoi l có th gi li du vết. Truy nguyên có th gi li khung. Các khung có th gi li các biến cc b. Vì thế`data`có th vn còn sng.

Mt mô hình dn dp ph biến là:```python
try:
    load_big()
except RuntimeError as exc:
    handle(exc)
    exc = None
```Hoc tránh lưu tr ngoi l lâu hơn mc cn thiết.

Chui lưu gi trông như thế này:```text
exception
    traceback
        frame
            locals
                large object
```Hiu khung giúp gii thích hành vi này.

## 28.27 Các đối tượng khung mang tính nội tâm, không miễn phí

Khung ni tâm rt mnh m, nhưng nó có chi phí.

Các hot động như thế này có th buc to hoc đồng b hóa đối tượng khung:```python
inspect.currentframe()
sys._getframe()
locals()
traceback inspection
debugger hooks
coverage tracing
```Điu này có th nh hưởng đến:```text
performance
memory lifetime
local variable synchronization
optimizer freedom
debugging visibility
```Đối vi mã ng dng thông thường, hãy tránh xem xét ni b khung trong các đường dn nóng. Đối vi trình g li, trình lược t và công c thi gian chy, vic xem xét ni b khung là điu cn thiết.

## 28.28 Thực thi khung đơn giản

Mt mô hình thc hin chc năng đơn gin hóa:```c
PyObject *
run_function(PyFunctionObject *func, PyObject **args, int nargs)
{
    Frame frame;

    frame.code = func->code;
    frame.globals = func->globals;
    frame.builtins = get_builtins(func->globals);
    frame.localsplus[0] = args[0];
    frame.localsplus[1] = args[1];
    frame.stack_pointer = frame.stack;
    frame.instruction_pointer = frame.code->first_instruction;

    return eval_frame(&frame);
}
```Điu này b qua nhiu chi tiết thc tế:```text
keyword arguments
defaults
closures
cell variables
free variables
generators
coroutines
exceptions
tracing
profiling
reference ownership
specialization
thread state
recursion checks
```Tuy nhiên, hình dng vn chính xác: lnh gi hàm chun b mt khung, sau đó vòng đánh giá s chy khung đó.

## 28.29 Bố cục khung đơn giản

B cc dy hc:```c
typedef struct {
    CodeObject *code;
    DictObject *globals;
    DictObject *builtins;

    Object **localsplus;
    Object **stack_pointer;

    Instruction *instruction_pointer;

    ExceptionState exception_state;

    struct Frame *previous;
} Frame;
```Ý tưởng quan trng là các v trí cc b và giá tr ngăn xếp thường được lưu tr gn nhau để thc thi hiu qu.

V mt khái nim:```text
frame memory
    fixed metadata
    locals and cells
    value stack
```Trình biên dch tính toán cn bao nhiêu v trí cc b và v trí ngăn xếp.

## 28:30 Khu vực Localsplus

CPython s dng mt vùng kết hp cho d liu cc b và d liu dng ngăn xếp trong các khung thc thi ca nó.

B cc khái nim:```text
localsplus
    fast locals
    cell variables
    free variables
    value stack
```Vì:```python
def f(a, b):
    c = a + b
    return c
```B cc có th được hiu là:```text
localsplus
    [0] a
    [1] b
    [2] c
    [3...] value stack area
```Đối vi các bao đóng, các ô và các biến t do cũng chiếm các v trí mà đối tượng mã đã biết.

Cách b trí nh gn này làm gim chi phí phân b và ci thin địa phương.

## 28.31 Chuyển đổi trạng thái khung

Mt khung có th di chuyn qua nhiu trng thái.```text
created
    
executing
    
returned
```Trình to và coroutine thêm nhiu trng thái hơn:```text
created
    
suspended
    
executing
    
suspended
    
completed
```Mt đường dn ngoi l:```text
executing
    
exception raised
    
handler found
    
executing handler
```Hoc:```text
executing
    
exception raised
    
no handler
    
unwound
```Trng thái khung xác định nhng hot động nào là hp pháp. Mt máy phát đin đã hoàn thành không th tiếp tc. Không th nhp li máy phát đin đang chy.

## 28.32 Thực thi lại

Vic thc thi Python có th được thc hin li.

Mt khung có th thc thi mt lnh gi mã người dùng, to ra mt khung khác trước khi lnh đầu tiên kết thúc.

Ví d:```python
class X:
    def __add__(self, other):
        return 42

def f(a, b):
    return a + b

f(X(), X())
```các`BINARY_OP`hướng dn trong`f`cuc gi`X.__add__`, thc thi mt khung Python khác.

V mt khái nim:```text
frame f
    BINARY_OP
        calls __add__
            frame X.__add__
                return 42
    continue frame f
```Đây là lý do ti sao mô hình đánh giá ca CPython phi duy trì trng thái khung trong các lnh gi ca trình tr giúp C có th nhp li Python.

## 28.33 Khung và ngăn xếp C

Khung Python và ngăn xếp C có liên quan nhưng khác bit.

Lnh gi hàm Python to trng thái thc thi Python. Tùy thuc vào phiên bn CPython và đường dn cuc gi, ngăn xếp C cũng có th phát trin.

Trình thông dch đã làm vic theo thi gian để gim s đệ quy C không cn thiết trong các lnh gi Python, nhưng các lnh gi gc, lnh gi tin ích m rng và mt s đường dn thi gian chy vn liên quan đến ngăn xếp C.

S khác bit quan trng:```text
Python frame
    Python-level execution state

C stack frame
    native machine call state
```Truy nguyên Python hin th các khung Python, không phi mi khung ngăn xếp C bên trong trình thông dch.

## 28.34 Xóa khung

Các khung có th được xóa để gii phóng các tham chiếu.

Mt khung tham chiếu nhiu đối tượng:```text
locals
globals
builtins
stack values
trace function
exception state
previous frame
```Khi khung không còn cn thiết na, CPython phi gii phóng các tham chiếu đã s hu để có th thu thp các đối tượng.

Đối vi máy phát đin và coroutines, vic xóa phc tp hơn vì khung có th b treo. Đóng trình to phi gii phóng trng thái khung ca nó mt cách an toàn.

Ví d:```python
def gen():
    data = bytearray(100_000_000)
    yield 1

g = gen()
next(g)
del g
```Vic xóa trình to có th gii phóng khung treo và do đó gii phóng`data`, gi s không có tài liu tham kho nào khác tn ti.

## 28.35 Ví dụ kiểm tra khung

Chương trình này in mt ngăn xếp cuc gi đơn gin:```python
import sys

def print_stack():
    frame = sys._getframe()
    while frame is not None:
        print(frame.f_code.co_name, frame.f_lineno)
        frame = frame.f_back

def c():
    print_stack()

def b():
    c()

def a():
    b()

a()
```V mt khái nim, chui là:```text
print_stack
c
b
a
<module>
```S dòng chính xác ph thuc vào tp tin.

Ví d này cho thy cách các khung hình thành mt ngăn xếp thi gian chy được liên kết hin th vi mã Python.

## 28.36 Sự cân bằng trong thiết kế khung

Các khung nm gia hiu sut và ni tâm.

CPython mun các khung hình nhanh vì mi lnh gi Python đều s dng chúng. Nhưng Python cũng hin th các khung cho mã người dùng và các công c.

Điu này to ra căng thng:

| Mc tiêu | Áp lc |
|---|---|
| Cuc gi nhanh | Gi khung nh gn và bên trong |
| G li | Hin th các đối tượng khung hình phong phú |
| H sơ | Bo toàn siêu d liu cuc gi và đường dây |
| Truy nguyên | Gi đủ trng thái sau khi tht bi |
| Máy phát đin | H tr đình ch |
| Coroutine | H tr h thng treo không đồng b |
| Hiu qu b nh | Tránh gi li nhng tài liu tham kho không cn thiết |
| Kh năng tương thích | Bo tn API khung cp Python |

Phn ln công vic ca khung CPython là cân bng các ràng buc này.

## 28.37 Những hiểu lầm phổ biến

| Hiu lm | Đúng mu |
|---|---|
| Mt khung ging như mt đối tượng mã | Mt khung thc thi mt đối tượng mã |
| Mi đối tượng hàm có mt khung | Mi cuc gi đang hot động đều có trng thái khung riêng bit |
| Các biến cc b luôn tn ti trong mt lnh | Người dân địa phương chc năng thường s dng slot nhanh |
|`locals()`luôn là nơi lưu tr thc s | Trong các hàm, nó có th là dng xem hoc ánh x được đồng b hóa |
| Du vết ch là chui | Tracebacks khung tham chiếu và v trí mã |
| Máy phát đin khi động li mi ln | Máy phát đin ni li khung treo |
| Vic đóng ca gi cho toàn b khung bên ngoài tn ti | Thông thường chúng gi cho các tế bào cn thiết tn ti |
| Khung ni tâm là min phí | Nó có th nh hưởng đến hiu sut và tui th b nh |

## 28.38 Chiến lược đọc thực hành

Để nghiên cu các khung trong CPython, hãy bt đầu t hành vi  cp độ Python.

S dng:```python
import dis
import inspect
import sys
```Nghiên cu chc năng này:```python
def outer(x):
    y = x + 1

    def inner(z):
        return x + y + z

    return inner
```Thanh tra:```python
fn = outer(10)

print(outer.__code__.co_varnames)
print(outer.__code__.co_cellvars)
print(fn.__code__.co_freevars)
print(fn.__closure__)

dis.dis(outer)
dis.dis(fn)
```Sau đó ánh x đầu ra ti các khái nim sau:```text
fast locals
cell variables
free variables
code objects
function objects
frames
stack effects
closure cells
```Điu này đưa ra mt l trình c th t cú pháp Python đến phn bên trong khung.

## 28.39 Tóm tắt chương

Khung là bn ghi thc thi ca CPython cho khi mã Python đang chy. Nó liên kết mt đối tượng mã vi trng thái thi gian chy trc tiếp: cc b, toàn cc, ni dung, giá tr ngăn xếp, v trí lnh, trng thái ngoi l và ng cnh ca người gi.

Các khung gii thích các lnh gi hàm, thc thi mô-đun, ni dung lp, truy nguyên, g li, lp h sơ, đệ quy, trình to, coroutine, bao đóng và lưu gi b nh.

Mô hình chính là:```text
code object
    immutable instructions and metadata

frame
    mutable execution state for one execution

evaluation loop
    runs the frame until return, exception, yield, or suspension
```Hiu các khung làm cho vòng đánh giá tr nên c th. Trình thông dch không thc thi mã ngun tru tượng. Nó đang nâng cao trng thái khung thông qua các hướng dn mã byte.