Menu
CoddyTech

Bộ điều chỉnh quyền truy cập

Thuộc phần Lập trình hướng đối tượng trong hành trình Python của Coddy. Bài học 29 trên 64.

Bộ điều chỉnh quyền truy cập kiểm soát khả năng hiển thị của thuộc tính và phương thức trong lớp. Python dùng quy ước đặt tên thay vì từ khóa để kiểm soát quyền truy cập.

Đây là ví dụ về quyền truy cập công khai (không có tiền tố):

class Person:
    def __init__(self):
        self.name = "Coddy"      # Thuộc tính công khai
        
    def greet(self):             # Phương thức công khai
        return f"Hello, I'm {self.name}"

Truy cập các thành viên công khai từ bất cứ đâu:

person = Person()
print(person.name)           # Coddy
print(person.greet())        # Xin chào, mình là Coddy

Đây là ví dụ về quyền truy cập được bảo vệ (một dấu gạch dưới):

class Employee:
    def __init__(self):
        self._salary = 50000     # Thuộc tính (attribute) được bảo vệ
    
    def _calculate_bonus(self):  # Phương thức (method) được bảo vệ
        return self._salary * 0.1

    def show_bonus(self):
        return self._calculate_bonus()  # Có thể dùng trong lớp (class)

Truy cập các thành viên được bảo vệ (vẫn hoạt động nhưng không được khuyến nghị):

employee = Employee()
print(employee._salary)      # 50000: vẫn chạy nhưng không nên dùng
print(employee.show_bonus()) # 5000.0: cách làm đúng

Đây là ví dụ về quyền truy cập riêng tư (hai dấu gạch dưới):

class User:
    def __init__(self):
        self.__password = "secure123"   # Thuộc tính (attribute) riêng tư
        
    def __encrypt(self, data):          # Phương thức (method) riêng tư
        return f"Encrypted: {data}"
        
    def verify(self, input_password):
        # Các thành viên riêng tư có thể được truy cập bên trong lớp (class)
        return input_password == self.__password

Sử dụng đúng các thành viên riêng tư:

user = User()
print(user.verify("secure123"))  # True: dùng phương thức công khai
# print(user.__password)         # AttributeError: không thể truy cập trực tiếp

Đầu ra:

Coddy
Hello, I'm Coddy
50000
5000.0
True

Điểm chính: Bộ điều chỉnh quyền truy cập trong Python là các quy ước đặt tên: không có tiền tố = công khai (có thể truy cập ở mọi nơi), một dấu gạch dưới = được bảo vệ (chỉ dùng nội bộ), hai dấu gạch dưới = riêng tư (chỉ trong lớp). Các quy ước này giúp thiết lập ranh giới rõ ràng và ngăn việc vô tình sử dụng sai các thành phần bên trong lớp.

challenge icon

Thử thách

Trung bình

Trong thử thách này, bạn sẽ triển khai một lớp FileManager để minh họa các phạm vi truy cập của Python (công khai, được bảo vệ và riêng tư), đồng thời trải nghiệm lợi ích của việc kiểm thử toàn diện.

Chỉnh sửa filemanager.py để triển khai lớp FileManager theo các chú thích TODO. Tệp này có hướng dẫn chi tiết về cách triển khai:

  • Các phương thức công khai để thao tác với tệp
  • Các phương thức được bảo vệ (có tiền tố dấu gạch dưới đơn)
  • Các phương thức riêng tư (có tiền tố dấu gạch dưới kép)
  • Các phương thức tương tác với nhau để minh họa tính đóng gói

Tự làm thử

from file_manager import FileManager

# Xử lý toàn diện các test case
test_case = input()

if test_case == "basic_test":
    # Tạo một instance của FileManager
    manager = FileManager()
    # Gọi phương thức read_file
    print(manager.read_file("example.txt"))
    # Gọi phương thức get_file_content
    print(manager.get_file_content("example.txt"))

elif test_case == "protected_access":
    # Tạo một instance của FileManager
    manager = FileManager()
    # Thử gọi phương thức protected
    # Có thể truy cập các phương thức protected, nhưng chúng dành cho việc sử dụng nội bộ
    print(manager._check_permissions("example.txt"))
    print("Note: Protected methods are accessible but intended for internal use only")

elif test_case == "private_access":
    # Tạo một instance của FileManager
    manager = FileManager()
    try:
        # Thử gọi trực tiếp phương thức private
        print(manager.__decrypt_content("some content"))
    except AttributeError as e:
        print(f"Error: {e}")
        print("Private methods are name-mangled and cannot be accessed directly")
    
    # Truy cập bằng tên đã biến đổi
    print(manager._FileManager__decrypt_content("some content"))
    print("Note: Accessed private method using name-mangled form")

elif test_case == "method_chaining":
    # Tạo một instance của FileManager
    manager = FileManager()
    # Minh họa cách get_file_content gọi nội bộ cả phương thức protected và private
    print("Calling get_file_content which internally uses protected and private methods:")
    print(manager.get_file_content("example.txt"))

elif test_case == "multiple_files":
    # Tạo một instance của FileManager
    manager = FileManager()
    # Xử lý nhiều tệp
    files = ["document.txt", "image.jpg", "data.csv"]
    
    for file in files:
        print(f"\
Processing {file}:")
        print(manager.read_file(file))
        print(manager.get_file_content(file))

elif test_case == "name_mangling":
    # Tạo một instance của FileManager
    manager = FileManager()
    # Minh họa cách biến đổi tên
    print("Python's name mangling for private methods:")
    print("Attempting direct access would fail with AttributeError")
    print("Using mangled name:")
    print(manager._FileManager__decrypt_content("private data"))
    print("\
Name mangling is Python's mechanism to prevent accidental access")
    print("It renames __method to _ClassName__method internally")
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Python online