- Namespace là hệ thống đặt tên duy nhất cho các đối tượng (biến, hàm, lớp) trong Python.
- Mỗi namespace là một ánh xạ từ tên → đối tượng (như một từ điển).
- Namespace được tạo tại thời điểm runtime.
Bài 15 - Python Namespace And Scope
Bài 15 - Python Namespace And Scope
I. Giới thiệu
Namespace (không gian tên) và Scope (phạm vi) là hai khái niệm cốt lõi trong Python giúp quản lý việc truy cập biến, hàm, và lớp trong chương trình. Hiểu rõ chúng giúp tránh lỗi và viết mã hiệu quả hơn.
II. Namespace (Không gian tên)
1. Định nghĩa
- Namespace là hệ thống đặt tên duy nhất cho các đối tượng (biến, hàm, lớp) trong Python.
- Mỗi namespace là một ánh xạ từ tên → đối tượng (như một từ điển).
- Namespace được tạo tại thời điểm runtime.
2. Phân loại Namespace
Có 3 loại chính:
- Built-in Namespace:
Chứa các hàm và biến sẵn có của Python (vd:print()
,len()
).
Tồn tại từ khi trình thông dịch khởi động. - Global Namespace:
Chứa các tên được định nghĩa ở cấp module (file.py
).
Tồn tại đến khi chương trình kết thúc. - Local Namespace:
Chứa các tên trong hàm hoặc lớp.
Tồn tại khi hàm/lớp được gọi và hủy khi kết thúc.
3. Ví dụ
# Built-in namespace: print, len, list, ...
# Global namespace: global_var, outer_func
global_var = 10 # Global namespace
def outer_func():
outer_var = 20 # Local namespace của outer_func
def inner_func():
inner_var = 30 # Local namespace của inner_func
print(inner_var)
inner_func()
outer_func()
III. Scope (Phạm vi)
1. Định nghĩa
- Scope là vùng mã nơi một namespace có thể được truy cập trực tiếp.
- Quyết định khả năng "nhìn thấy" của một biến tại vị trí trong code.
2. Quy tắc LEGB
Python tìm kiếm tên theo thứ tự:
- L (Local): Trong hàm/lớp hiện tại.
- E (Enclosing): Trong hàm bao ngoài (nếu có).
- G (Global): Ở cấp module.
- B (Built-in): Trong namespace built-in.
3. Các loại Scope
- Local Scope: Biến trong hàm hiện tại.
- Enclosing Scope: Biến trong hàm bao ngoài (closure).
- Global Scope: Biến ở cấp module.
- Built-in Scope: Biến built-in.
IV. Ví dụ minh họa
1. Cơ bản
x = 10 # Global scope
def foo():
y = 20 # Local scope
print(x) # Tìm thấy x trong global scope
foo()
print(y) # Lỗi! y không tồn tại trong global scope
2. Enclosing Scope
def outer():
z = 30 # Enclosing scope
def inner():
print(z) # Truy cập z từ enclosing scope
inner()
outer()
3. Global vs Local
counter = 0 # Global
def increment():
global counter # Khai báo sử dụng global variable
counter += 1
increment()
print(counter) # 1
4. LEGB Rule
name = "Global" # Global
def outer():
name = "Enclosing" # Enclosing
def inner():
name = "Local" # Local
print(name) # Ưu tiên Local → Output: "Local"
inner()
outer()
V. Lưu ý quan trọng
global
keyword:
Cho phép sửa đổi biến toàn cục trong hàm.total = 0 def update(): global total total = 100
nonlocal
keyword:
Truy cập biến trong enclosing scope (không phải global).def outer(): count = 0 def inner(): nonlocal count count = 10 # Sửa biến của outer()
- Biến chỉ đọc trong nested scope:
Python cho phép đọc biến từ enclosing scope, nhưng nếu gán, nó sẽ tạo biến mới ở local scope (trừ khi dùngnonlocal
/global
). - Namespace động:
Có thể kiểm tra namespace bằng:locals()
: Trả về dictionary của local namespace.globals()
: Trả về dictionary của global namespace.
VI. Bài tập thực hành
Kiểm tra LEGB:
Dự đoán output của đoạn mã sau:
x = 5
def func1():
x = 10
def func2():
print(x)
func2()
func1() # Output?
Giải thích:
Hàm func2
tìm x
theo LEGB:
- Local (func2): ❌
- Enclosing (func1): ✅
x=10
→ Output: 10
Tổng kết
Khái niệm | Mô tả |
---|---|
Namespace | Hệ thống quản lý tên → đối tượng (Built-in/Global/Local) |
Scope | Vùng mã nơi namespace được truy cập trực tiếp (LEGB) |
global | Chỉ định sử dụng biến toàn cục trong hàm |
nonlocal | Chỉ định sử dụng biến từ enclosing scope (closure) |
Hiểu rõ Namespace và Scope giúp tránh lỗi logic về biến, quản lý bộ nhớ hiệu quả và thiết kế chương trình rõ ràng!