Trong hướng dẫn này, chúng ta sẽ tìm hiểu về biến private trong các class Python.
Python có biến private thực sự không?
Python không có khái niệm biến private như các ngôn ngữ khác (Java, C++). Tuy nhiên, cộng đồng Python đã thống nhất một quy ước đặt tên: biến bắt đầu bằng hai gạch dưới (__) được coi là "private" (chỉ mang ý nghĩa thông báo cho lập trình viên khác biết biến này dành cho dùng nội bộ trong class).
Ví dụ: __ten_bien, __gia_tri, v.v.
Tạo biến kiểu private và truy cập
Mặc dù đặt tên bắt đầu bằng __, các biến này vẫn có thể truy cập từ bên ngoài nhờ cơ chế name mangling của Python. Hãy xem ví dụ sau:
# Tạo class
class Sample:
def __init__(self, nv, pv):
# Biến bình thường
self.nv = nv
# Biến "private" (theo quy ước)
self.__pv = pv
# Tạo instance
sample = Sample('Biến bình thường', 'Biến private')
Thử truy cập hai biến:
# Truy cập biến bình thường
print(sample.nv) # Hoạt động bình thường
# Truy cập biến __pv trực tiếp
print(sample.__pv) # Gây ra AttributeError
Kết quả
Biến bình thường
---------------------------------------------------------------------------
AttributeError: 'Sample' object has no attribute '__pv'
Tại sao lại lỗi? Cơ chế Name Mangling
Python tự động đổi tên các biến bắt đầu bằng __ theo quy tắc: _TenClass__ten_bien. Do đó, __pv trong class Sample thực tế trở thành _Sample__pv.
Cách truy cập đúng:
print(sample._Sample__pv) # In ra: Biến private
Name Mangling cũng áp dụng cho phương thức
Cơ chế này không chỉ dành cho biến, mà cả phương thức (method):
class Sample:
def __init__(self, a):
self.a = a
# Phương thức "private"
def __get_a(self):
return self.a
sample = Sample(5)
# Gọi đúng tên sau name mangling
print(sample._Sample__get_a()) # Kết quả: 5
# Gọi sai tên gốc
print(sample.__get_a()) # AttributeError
Kết luận
Mục đích của __ không phải để ngăn cấm truy cập, mà để thông báo ý định thiết kế: biến/phương thức này chỉ nên dùng bên trong class. Name mangling giúp tránh xung đột tên khi kế thừa, không phải để bảo mật.