Chỉ dùng global khi thật sự cần gán tên ngoài
`global dem` làm phép gán trong hàm tác động lên tên `dem` ngoài hàm:
```python
dem = 0
def ghi_nhan():
global dem
dem = dem + 1
ghi_nhan()
ghi_nhan()
print(dem)
```
Kết quả là `2`. Nếu chỉ đọc `dem` mà không gán lại, không cần `global`. Với bài toán tính toán thông thường, trả kết quả bằng `return` rồi gán ở nơi gọi thường dễ theo dõi hơn là thay đổi biến ngoài từ trong hàm.
Bài luyện
Sau hai lời gọi `ghi_nhan()`, `dem` bằng bao nhiêu?
Mỗi lời gọi tăng một lần.
Có hai lời gọi.
global cho phép gán tên ngoài; 0→1→2.
Biến dem là số nguyên.
Lời giải
Mỗi lần gọi, `dem` ngoài hàm tăng 1 nhờ khai báo `global`; sau hai lần, giá trị là 2.
Bài luyện
Với `phi = 3` và `def tong_phi(gia): return gia + phi`, vì sao hàm không cần `global phi`?
phi là số 3, nhưng kiểu không phải lí do.
Chỉ đọc tên ngoài không cần khai báo global.
Biến ngoài vẫn tồn tại.
Đối số gia không quyết định global.
Lời giải
`tong_phi` đọc `phi` nhưng không có phép gán cho tên đó trong hàm. Vì thế không cần `global phi`.
List truyền vào có thể bị sửa tại chỗ
Tham số trong hàm là một tên cục bộ, nhưng nó có thể trỏ đến **cùng list** với đối số ở nơi gọi. `append` thay đổi chính list đó; gán tham số sang list mới lại không đổi list cũ:
```python
def them(A):
A.append(9)
def doi(A):
A = [0]
so = [2]
them(so)
print(so)
doi(so)
print(so)
```
Hai dòng đều là `[2, 9]`. Sau `them`, list gốc có thêm 9. Trong `doi`, phép gán chỉ đổi tên cục bộ A sang một list khác, nên list gốc vẫn `[2, 9]`. Đây là lí do không nên nói mọi đối số đều được “sao chép giá trị” như một vật tách rời.
Bài luyện
Sau khi gọi `them(so)` với `so = [2]`, so là gì?
append đã thêm vào list gốc.
append không xóa 2.
Tham số A và so cùng trỏ list; append thêm 9.
[0] xuất hiện trong hàm doi khác.
Lời giải
`them` gọi `A.append(9)` trên chính list mà `so` đang trỏ tới. List đổi từ `[2]` thành `[2,9]`.
Bài luyện
Sau lệnh `doi(so)` tiếp theo, so là gì?
[0] là list mới của tên cục bộ A.
Gán lại A không gán lại tên so ở ngoài.
Mã không append 0.
so vẫn trỏ list.
Lời giải
`doi` chỉ gán tên cục bộ A sang `[0]`; list mà `so` trỏ tới không đổi, vẫn `[2,9]`.
Đang học