Skip to main content

Bài 16 - Python Global, Local And Nonlocal variables

Mục tiêu: Hiểu rõ phạm vi (scope) của biến trong Python và cách sử dụng global, local, nonlocal.

1. Phạm vi biến (Variable Scope)

  • Khái niệm: Phạm vi biến là vùng code nơi biến được nhận diện và có thể truy cập.
  • Phân loại:
    • Local scope: Biến khai báo trong hàm.
    • Enclosing scope: Biến trong hàm chứa hàm lồng nhau.
    • Global scope: Biến khai báo ở file chính.
    • Built-in scope: Tên sẵn có trong Python (ví dụ: print, len).

2. Biến Local (Cục bộ)

  • Đặc điểm:
    • Khai báo bên trong hàm.
    • Chỉ truy cập được trong hàm đó.
    • Tồn tại từ lúc hàm được gọi đến khi hàm kết thúc.
  • Ví dụ:

    def my_func():
        local_var = 10  # Biến local
        print("Inside function:", local_var)  # Output: 10
    
    my_func()
    print("Outside function:", local_var)  # Lỗi: NameError

3. Biến Global (Toàn cục)

  • Đặc điểm:
    • Khai báo bên ngoài mọi hàm, thường ở đầu file.
    • Truy cập được mọi nơi trong file.
    • Muốn thay đổi giá trị trong hàm → dùng từ khóa global.
  • Ví dụ 1: Đọc biến global (không cần global):

    global_var = 20  # Biến global
    
    def read_global():
        print("Inside function:", global_var)  # Output: 20
    
    read_global()
  • Ví dụ 2: Sửa biến global (cần global):

    global_var = 20
    
    def modify_global():
        global global_var  # Khai báo sử dụng biến global
        global_var = 30    # Sửa giá trị
    
    modify_global()
    print("After modification:", global_var)  # Output: 30

4. Biến Nonlocal (Không cục bộ)

  • Đặc điểm:
    • Dùng trong hàm lồng nhau (nested functions).
    • Truy cập biến của hàm bao bọc (enclosing function).
    • Muốn thay đổi giá trị → dùng từ khóa nonlocal.
  • Ví dụ:

    python

     

    def outer_func():
        nonlocal_var = "Hello"  # Biến của hàm outer
    
        def inner_func():
            nonlocal nonlocal_var  # Khai báo sử dụng biến nonlocal
            nonlocal_var = "World"  # Sửa giá trị
    
        inner_func()
        print("Inside outer:", nonlocal_var)  # Output: World
    
    outer_func()

5. So Sánh Global, Local, Nonlocal

Loại biếnTừ khóaPhạm vi truy cậpMục đích
LocalKhôngTrong hàm chứa nóBiến tạm trong hàm
GlobalglobalToàn bộ fileBiến dùng chung xuyên suốt
NonlocalnonlocalHàm lồng nhau (enclosing)Thay đổi biến của hàm cha

6. Lưu ý Quan Trọng

  1. Ưu tiên phạm vi:

    Local → Enclosing → Global → Built-in

    (Áp dụng quy tắc LEGB khi tìm kiếm biến).

  2. Không dùng global/nonlocal với biến chưa tồn tại:

    def broken_func():
        global new_var  # Lỗi nếu new_var chưa được khai báo ở global scope!
        new_var = 100
  3. Hạn chế lạm dụng global: Dễ gây xung đột dữ liệu, khó debug.

7. Bài Tập Thực Hành

Câu 1: Đoán output

x = 5
def foo():
    x = 10
    def bar():
        nonlocal x
        x = 20
    bar()
    print(x)  # Output: ?
foo()
print(x)      # Output: ?

<details> <summary>Đáp án</summary> Inside foo: 20 (nonlocal thay đổi x của foo) Global x: 5 (biến global không bị ảnh hưởng) </details>

Câu 2: Sửa lỗi

def outer():
    count = 0
    def increment():
        count += 1  # Lỗi vì không dùng nonlocal
    increment()
outer()

<details> <summary>Sửa</summary> Thêm: nonlocal count trong hàm increment() </details>

Tài liệu Tham Khảo

Chúc bạn học tốt! 🐍