Python 类和方法

魔术方法

概述

  1. Python 的魔术方法(magic methods)是以双下划线开头、双下划线结尾的特殊方法, 例如 initstrlen.它们由 Python 解释器自动调用,用于让对象支持各种内置语法、运算符、函数和行为.
+ 代码示例
class Box:
    # 创建 Box 对象时,把传入的列表保存到 self.items
    def __init__(self, items):
        self.items = items
    # 当你写 len(b) 时,Python 自动调用 b.__len__()
    def __len__(self):
        return len(self.items)
    def __str__(self):
        return f"Box with {len(self)} items"

b = Box([1,2,3])
print(len(b))
print(b)

函数方法

  1. 对于函数方法, python有一种约定俗成的写法.
    1. 单下划线前缀 _method: 表示这是一个内部方法,不建议在类外部直接调用.这只是约定, 外部依然可以调用obj._method(), 不会报错.
    2. 双下划线前缀 __method: __method 会触发名称改写, Python会把方法名改成 _类名__方法名, 避免子类意外覆盖父类的方法或属性和外部的直接访问.外部使用obj.__secret()会报错, 使用obj._MyClass__secret()可以访问.这是在类定义阶段完成的,不是运行时动态处理的.
      + 代码示例
      class Parent:
          def __init__(self):
              self.__value = 42   # 会被改写为 _Parent__value
      
          def __secret(self):     # 会被改写为 _Parent__secret
              print("Parent secret:", self.__value)
      
          def call_secret(self):
              self.__secret()     # 调用的是 _Parent__secret
      
      
      class Child(Parent):
          def __init__(self):
              # super().__init__() 的作用是 在子类中调用父类的构造函数,确保父类的初始化逻辑被正确执行
              # super() 返回一个“父类的代理对象”,让你可以调用父类的方法,而不需要写死父类名字
              # 等价于: 找到当前类的父类, 调用父类的 __init__ 方法, 让父类负责初始化它定义的属性.
              super().__init__()
              self.__value = 100  # 会被改写为 _Child__value
      
          def __secret(self):     # 会被改写为 _Child__secret
              print("Child secret:", self.__value)
      
          def call_child_secret(self):
              self.__secret()     # 调用的是 _Child__secret
      
      
      p = Parent()
      c = Child()
      
      print("=== 调用父类方法 ===")
      p.call_secret()        # 调用 Parent 的 __secret
      c.call_secret()        # 仍然调用 Parent 的 __secret(不会被子类覆盖)
      
      print("\n=== 调用子类方法 ===")
      c.call_child_secret()  # 调用 Child 的 __secret
      
      print("\n=== 外部访问 ===")
      
      # 正确访问方式(名称改写后的真实名字)
      # p.__secret()        # ❌ AttributeError
      p._Parent__secret()    # ✔️ 可以访问
      
      # c.__secret()        # ❌ AttributeError
      c._Child__secret()     # ✔️ 可以访问
      
      print("\n=== 查看对象属性字典 ===")
      print("Parent __dict__:", p.__dict__)
      print("Child __dict__:", c.__dict__)
      
      """
      Output:
      === 调用父类方法 ===
      Parent secret: 42
      Parent secret: 42
      
      === 调用子类方法 ===
      Child secret: 100
      
      === 外部访问 ===
      Parent secret: 42
      Child secret: 100
      
      === 查看对象属性字典 ===
      Parent __dict__: {'_Parent__value': 42}
      Child __dict__: {'_Parent__value': 42, '_Child__value': 100}
      """
      
    3. 普通方法(没有下划线)就是公开方法, 推荐给外部使用.

参考链接

  1. python官方教程
  2. python官方教程: Data model
  3. python教程