Menu
CoddyTech

访问修饰符

本课属于 Coddy Python 学习旅程的“面向对象编程”单元。第 29 课,共 64 课。

访问修饰符用于控制类属性和方法的可见性。Python 使用命名约定而不是关键字来控制访问权限。

下面是一个公开访问(没有前缀)的示例:

class Person:
    def __init__(self):
        self.name = "Coddy"      # 公有属性
        
    def greet(self):             # 公有方法
        return f"Hello, I'm {self.name}"

可以从任何位置访问公共成员:

person = Person()
print(person.name)           # Coddy
print(person.greet())        # Hello, I'm Coddy

下面是受保护访问(单下划线)的示例:

class Employee:
    def __init__(self):
        self._salary = 50000     # 受保护的属性
    
    def _calculate_bonus(self):  # 受保护的方法
        return self._salary * 0.1

    def show_bonus(self):
        return self._calculate_bonus()  # 可以在类内部使用

访问受保护成员(虽然可行,但不推荐):

employee = Employee()
print(employee._salary)      # 50000:能用,但不推荐
print(employee.show_bonus()) # 5000.0:推荐的做法

下面是一个私有访问(双下划线)的示例:

class User:
    def __init__(self):
        self.__password = "secure123"   # 私有属性
        
    def __encrypt(self, data):          # 私有方法
        return f"Encrypted: {data}"
        
    def verify(self, input_password):
        # 可以在类内部访问私有成员
        return input_password == self.__password

正确使用私有成员:

user = User()
print(user.verify("secure123"))  # True,使用公开方法
# print(user.__password)         # AttributeError,不能直接访问

输出:

Coddy
Hello, I'm Coddy
50000
5000.0
True

要点:Python 的访问修饰符是命名约定:没有前缀表示公有(可在任何地方访问),单下划线表示受保护(仅供内部使用),双下划线表示私有(仅限类内部)。这些约定有助于明确界限,防止意外误用类的内部内容。

challenge icon

挑战

中等

在这个挑战中,你将实现一个 FileManager 类,演示 Python 的访问修饰符(公有、受保护和私有),同时体验全面测试的好处。

编辑 filemanager.py,按照 TODO 注释实现 FileManager 类。文件中包含实现以下内容的详细说明:

  • 用于文件操作的公有方法
  • 带单下划线前缀的受保护方法
  • 带双下划线前缀的私有方法
  • 展示封装特性的方法交互

亲手试试

from file_manager import FileManager

# 综合测试用例处理程序
test_case = input()

if test_case == "basic_test":
    # 创建一个 FileManager 实例
    manager = FileManager()
    # 调用 read_file 方法
    print(manager.read_file("example.txt"))
    # 调用 get_file_content 方法
    print(manager.get_file_content("example.txt"))

elif test_case == "protected_access":
    # 创建一个 FileManager 实例
    manager = FileManager()
    # 尝试调用受保护方法
    # 受保护方法可以访问,但主要供内部使用
    print(manager._check_permissions("example.txt"))
    print("Note: Protected methods are accessible but intended for internal use only")

elif test_case == "private_access":
    # 创建一个 FileManager 实例
    manager = FileManager()
    try:
        # 尝试直接调用私有方法
        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")
    
    # 使用名称改写后的形式访问
    print(manager._FileManager__decrypt_content("some content"))
    print("Note: Accessed private method using name-mangled form")

elif test_case == "method_chaining":
    # 创建一个 FileManager 实例
    manager = FileManager()
    # 展示 get_file_content 如何在内部调用受保护方法和私有方法
    print("Calling get_file_content which internally uses protected and private methods:")
    print(manager.get_file_content("example.txt"))

elif test_case == "multiple_files":
    # 创建一个 FileManager 实例
    manager = FileManager()
    # 处理多个文件
    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":
    # 创建一个 FileManager 实例
    manager = FileManager()
    # 展示名称改写
    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 icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Python 在线编译器