24. Hằng, Tên và Địa phương

Đối tượng mã không lưu trữ mã nguồn Python dưới dạng văn bản. Nó lưu trữ các bảng nhỏ gọn và các hướng dẫn mã byte tham chiếu đến các bảng đó theo chỉ mục.

Ba trong số các bảng quan trọng nhất là:```text id="mx2a9w" co_consts co_names co_varnames


Đối vi chc năng này:```python id="wg80pj"
def f(a):
    b = len(a)
    return b + 1
```Ca hàng CPython:```text id="jxh1ou"
constants:
    None
    1

names:
    len

local variables:
    a
    b
```Sau đó, các hướng dn mã byte s tham chiếu đến các mc đó theo ch mc.

## 24.1 Vị trí trong Đường dẫn biên dịch

Các hng s, tên và địa phương được tp hp trong quá trình biên dch.```text id="la84x8"
AST
    
symbol table
    
compiler
    
instruction stream
    
constant table
    
name table
    
local variable table
    
code object
```Các bng này là mt phn ca đối tượng mã.

Trình thông dch s dng chúng khi thc thi mã byte.```text id="gvqxes"
LOAD_CONST 1
LOAD_GLOBAL 0
LOAD_FAST 0
STORE_FAST 1
```Mi toán hng s lp ch mc vào mt trong các bng ca đối tượng mã.

## 24.2 Tại sao đối tượng mã lại sử dụng bảng

Mã byte cn phi nh gn.

Thay vì nhúng trc tiếp các đối tượng hoc chui Python đầy đủ vào bên trong mi lnh, CPython lưu tr chúng mt ln trong mt bng.

Ví d:```python id="y6ymck"
def f():
    print("hello")
    print("hello")
```Chui`"hello"`có th xut hin mt ln trong`co_consts`.

Tên`"print"`có th xut hin mt ln trong`co_names`.

Mã byte tham chiếu chúng theo ch mc.

V mt khái nim:```text id="y1yh5e"
co_consts:
    0: None
    1: "hello"

co_names:
    0: "print"

bytecode:
    LOAD_GLOBAL 0       print
    LOAD_CONST 1        "hello"
    CALL
    POP_TOP

    LOAD_GLOBAL 0       print
    LOAD_CONST 1        "hello"
    CALL
    POP_TOP
```Điu này làm gim s trùng lp và mang li cho trình thông dch v trí tra cu n định.

## 24.3 Hằng số

Các hng s là các giá tr bng ch và các to phm được biên dch được lưu tr trong`co_consts`.

Các hng s ph biến bao gm:```text id="0sqmi6"
None
True
False
integers
floats
complex numbers
strings
bytes
tuples of constants
frozensets of constants
nested code objects
```Ví d:```python id="0bigls"
def f():
    return 123, "abc", None
```Thanh tra:```python id="unotfl"
print(f.__code__.co_consts)
```Hình dng đin hình:```text id="zsqktw"
(None, 123, 'abc')
```B d liu được hàm tr v có th t nó được xây dng t các hng s hoc nó có th được lưu tr dưới dng mt b d liu không đổi nếu trình biên dch có th gp nó mt cách an toàn.

## 24.4`None`Hằng số

Hu hết các đối tượng mã bao gm`None`TRONG`co_consts`.

Ví d:```python id="mxsc3g"
def f():
    x = 1
```Mc dù ngun không ghi rõ ràng`return None`, hàm tr v`None`ngm.

Trình biên dch phi có kh năng phát ra:```text id="b7i1tf"
LOAD_CONST None
RETURN_VALUE
``` cp độ mô-đun, CPython cũng thường phát ra kết qu cui cùng`RETURN_VALUE`vi`None`để kết thúc vic thc hin.

## 24.5 Hằng số

Ch s thường xut hin trong`co_consts`.

Ví d:```python id="y88hr2"
def f():
    return 10 + 20
```AST có th cha`10 + 20`, nhưng trình biên dch có th gp cái này thành`30`.

Thanh tra:```python id="y7a6vi"
import dis

def f():
    return 10 + 20

print(f.__code__.co_consts)
dis.dis(f)
```Bn có th ch thy`30`như mt hng s được ti.

Gp liên tc là bo th. CPython có th gp các biu thc an toàn và mang tính quyết định ti thi đim biên dch. Nó không th gp các biu thc vi các hiu ng thi gian chy.

Ví d:```python id="3nempa"
def f():
    return 10 + x

xkhông được biết tại thời điểm biên dịch, vì vậy điều này không thể trở thành một hằng số.

24.6 Hằng số chuỗi và byte

Chuỗi ký tự và byte xuất hiện trongco_consts.

Ví dụ:python id="086py8" def f(): return "hello", b"world" Thanh tra:python id="mwit9a" print(f.__code__.co_consts) Các chuỗi ký tự liền kề có thể được nối trong quá trình biên dịch:```python id="yn2nfn" def f(): return "hello" "world"


Kết qu là mt hng s:```text id="g8bxm7"
"helloworld"
```## 24.7 Hằng số bộ dữ liệu

Các b ch cha hng s có th được lưu tr dưới dng hng s.

Ví d:```python id="u33byh"
def f():
    return (1, 2, 3)
```Trình biên dch có th lưu tr toàn b b d liu:```text id="kw4dlg"
(1, 2, 3)
```TRONG`co_consts`.

Nhưng nếu mt phn t là động:```python id="f0psq9"
def f(x):
    return (1, x, 3)
```b d liu phi được xây dng trong thi gian chy.

Mu biên dch:```text id="0f7svq"
LOAD_CONST 1
LOAD_FAST x
LOAD_CONST 3
BUILD_TUPLE 3
```Trình biên dch phân bit các vùng cha hng s bt biến vi các vùng cha được xây dng trong thi gian chy.

## 24.8 Hằng số tập hợp đông lạnh

Các hng s ca tp hp có th thay đổi được, vì vy bn thân mt tp hp không th là hng s trong mã byte.

Nhưng CPython có th s dng`frozenset`hng s để kim tra thành viên được ti ưu hóa.

Ví d:```python id="a4bjga"
def is_small(x):
    return x in {1, 2, 3}
```Ngun s dng mt ch c định. Trình biên dch có th biên dch tư cách thành viên da vào mt`frozenset`không đổi vì tp hp này ch được s dng để kim tra tư cách thành viên.

V mt khái nim:```text id="y0dtbp"
LOAD_FAST x
LOAD_CONST frozenset({1, 2, 3})
CONTAINS_OP
```Điu này tránh vic xây dng li tp hp mi khi hàm chy.

Trình biên dch phi bo toàn ng nghĩa. S ti ưu hóa này hp l cho các hng s vì tư cách thành viên trong`{1, 2, 3}`Và`frozenset({1, 2, 3})`đưa ra kết qu tương t cho hot động có liên quan.

## 24.9 Các đối tượng mã lồng nhau dưới dạng hằng số

Các hàm lng nhau lưu tr các đối tượng mã ca chúng trong`co_consts`.

Ví d:```python id="n17lr5"
def outer():
    def inner():
        return 1
    return inner
```Thanh tra:```python id="56jqwc"
for const in outer.__code__.co_consts:
    print(repr(const))
```Bn s tìm thy mt đối tượng mã cho`inner`.

Trong thi gian chy, hàm bên ngoài thc thi mã byte ti đối tượng mã lng nhau và to đối tượng hàm:```text id="xrarxf"
LOAD_CONST <code object inner>
MAKE_FUNCTION
STORE_FAST inner
```Đối tượng mã lng nhau là d liu được biên dch không đổi. Đối tượng hàm được to trong thi gian chy.

## 24.10 Bảng tên`co_names`lưu trữ các tên tượng trưng được sử dụng bởi các hoạt động mã byte không phải là biến cục bộ hoặc biến đóng nhanh.

Chúng bao gm:```text id="b9fx1t"
global names
builtin lookup names
attribute names
imported module names
method names
some class body names
```Ví d:```python id="sl10xc"
def f(xs):
    return len(xs)
```Thanh tra:```python id="il1b6j"
print(f.__code__.co_names)
```Hình dng đin hình:```text id="6whwgp"
('len',)
```Mã byte ti`len`thông qua mt ch mc tên.

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

Mt cái tên trong`co_names`có th đề cp đến toàn cu hoc ni dung trong thi gian chy.

Ví d:```python id="pxxc09"
def f(xs):
    return len(xs)

lenkhông phải là địa phương. Nó được tải bằng cách sử dụng các quy tắc tra cứu toàn cầu.

Kiểm tra tra cứu thời gian chạy:text id="d2z1ce" function globals then builtins Đối tượng mã không lưu trữ hàm dựng sẵn thực tếlen. Nó lưu trữ chuỗi tên"len".

Điều đó có nghĩa là việc thay đổi toàn cầu có thể ảnh hưởng đến việc thực thi:```python id="oghwkx" def f(xs): return len(xs)

len = lambda x: 999

print(f([1, 2, 3])) ```Bên trong mô-đun đó,lenbây giờ giải quyết thành lambda toàn cầu, không phải nội trang.

24.12 Tên thuộc tính

Tên thuộc tính cũng tồn tại trongco_names.

Ví dụ:python id="trjd66" def f(obj): return obj.value Thanh tra:python id="vrg5um" print(f.__code__.co_names) Hình dạng điển hình:text id="133tbx" ('value',) Mã byte sử dụng:text id="f1yae8" LOAD_FAST obj LOAD_ATTR value Chuỗi"value"được lưu trữ một lần trongco_names.

Điều này tách biệt với tra cứu toàn cầu. Cùng một bảng lưu trữ các chuỗi tên được sử dụng bởi nhiều họ lệnh.

24.13 Tên phương thức

Cú pháp gọi phương thức cũng sử dụng tên.

Ví dụ:```python id="pwnbfj" def f(obj): return obj.run()


`run`xut hin `co_names`.

Trình biên dch có th đưa ra các hướng dn hướng cuc gi chuyên dng tùy thuc vào phiên bn Python, nhưng tên phương thc vn xut phát t bng tên.

Mã byte khái nim:```text id="vjlnib"
LOAD_FAST obj
LOAD_METHOD run
CALL 0
```Bng tên lưu tr chui tên phương thc.

## 24.14 Nhập tên

Nhp khu cũng s dng bng tên.

Ví d:```python id="sf2lb3"
def f():
    import os
    return os.getcwd()
```Bng tên có th cha:```text id="pi43tc"
os
getcwd
```Bng cc b cha`os`nếu quá trình nhp nm trong hàm vì quá trình nhp liên kết vi mt biến cc b.

S khác bit này quan trng:```text id="hc8fxf"
co_names:
    names needed by import and attribute operations

co_varnames:
    local binding created by import os
```Nhp khu là các bài tp t góc độ b cc biến cc b.

## 24.15 Biến cục bộ`co_varnames`lưu trữ tên biến cục bộ nhanh.

Ví d:```python id="nyh7qv"
def f(a, b):
    c = a + b
    return c
```Thanh tra:```python id="g0h75x"
print(f.__code__.co_varnames)
```Hình dng đin hình:```text id="ja0vd0"
('a', 'b', 'c')
```Khung lưu tr các giá tr cc b theo b cc ging như mng. Lp ch mc mã byte vào b cc này.```text id="x503qw"
LOAD_FAST 0    a
LOAD_FAST 1    b
STORE_FAST 2   c
```Đây là lý do ti sao truy cp cc b nhanh hơn tra cu t đin toàn cu.

## 24.16 Tham số cục bộ

Các tham s chc năng xut hin đầu tiên trong`co_varnames`.

Ví d:```python id="9b48mv"
def f(a, b, c=0):
    d = a + b + c
    return d

co_varnamesthường bắt đầu:```text id="83pbbd" ('a', 'b', 'c', 'd')


Giá tr mc định được lưu tr trên đối tượng hàm, không trc tiếp trong đối tượng mã.```python id="9q7w3m"
print(f.__defaults__)
print(f.__code__.co_varnames)
```## 24.17 Người dân địa phương chỉ có vị trí và từ khóa

Đối tượng mã lưu tr s lượng đối s riêng bit vi`co_varnames`.

Ví d:```python id="87asnp"
def f(a, b, /, c, *, d):
    return a, b, c, d
```Thanh tra:```python id="kbjcbq"
code = f.__code__

print(code.co_posonlyargcount)
print(code.co_argcount)
print(code.co_kwonlyargcount)
print(code.co_varnames)
```Tên địa phương được lưu tr trong`co_varnames`, trong khi s đếm xác định cách din gii các mc hàng đầu.

V mt khái nim:```text id="h79uky"
co_varnames:
    a, b, c, d

co_posonlyargcount:
    2

co_argcount:
    3

co_kwonlyargcount:
    1
```Máy gi s dng siêu d liu này để liên kết đối s.

## 24.18`*args`Và`**kwargs`Tên đối số biến cũng xuất hiện trong`co_varnames`.

Ví d:```python id="a78joh"
def f(a, *args, **kwargs):
    return args, kwargs
```Thanh tra:```python id="57zit6"
code = f.__code__

print(code.co_varnames)
print(code.co_flags)
```các`co_flags`trường ghi li rng hàm chp nhn các đối s t khóa hoc v trí thay đổi.

Nhng cái tên`args`Và`kwargs`là các khe địa phương.

## 24.19 Giá trị tạm thời không được đặt tên cục bộ

Ngăn xếp đánh giá gi các giá tr tm thi.

Ví d:```python id="yqtwg0"
def f(a, b, c):
    return a + b * c

co_varnameschứa:text id="gvos5r" a b c Nó không chứa các giá trị trung gian tạm thời nhưb * c.

Kết quả trung gian đó nằm trong ngăn xếp đánh giá của khung.

Ngăn xếp khái niệm:```text id="3snx1b" LOAD_FAST a stack: a LOAD_FAST b stack: a, b LOAD_FAST c stack: a, b, c BINARY_OP * stack: a, temp BINARY_OP + stack: result RETURN_VALUE stack empty


## 24.20 Biến ô`co_cellvars`lưu trữ các địa phương được nắm bắt bởi các hàm lồng nhau.

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

    def inner():
        return x

    return inner
```Thanh tra:```python id="91ti0b"
print(outer.__code__.co_cellvars)
```Kết qu đin hình:```text id="n2byuv"
('x',)
```Bên trong`outer`, `x`phi sng trong tế bào vì`inner`có th truy cp nó sau`outer`tr li.

Biến cc b tr thành b lưu tr đóng được h tr bng đống.

## 24.21 Biến miễn phí`co_freevars`lưu trữ tên được chụp từ phạm vi kèm theo.

S dng cùng mt ví d:```python id="b3corm"
inner = outer()
print(inner.__code__.co_freevars)
```Kết qu đin hình:```text id="i1hd7z"
('x',)
```Bên trong`inner`, `x`không phi là mt người dân địa phương bình thường. Nó được ti t mt ô đóng ca.

Mã byte khái nim:```text id="o8g8eg"
LOAD_DEREF x
RETURN_VALUE
```Đối tượng mã ghi li tên. Đối tượng hàm mang ô thc tế.

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

Bên trong mt chc năng được ti ưu hóa thông thường, người dân địa phương