小甲鱼Python学习笔记

属性访问基础回顾

  • 直接访问:对象.属性(如 c.x)
  • BIF 访问方式
    • getattr(obj, name[, default]):获取属性,无则返回默认值
    • setattr(obj, name, value):设置属性
    • delattr(obj, name):删除属性
  • property 函数:绑定属性的获取、设置、删除方法
    • 用法:property(get方法, set方法, del方法)
    • 效果:通过属性名间接操作对应方法

核心属性访问魔法方法

  • getattr(self, name)
    • 触发时机:访问不存在的属性时
    • 作用:自定义不存在属性的访问逻辑
  • getattribute(self, name)
    • 触发时机:任何属性被访问时(优先级最高)
    • 注意:需通过 super() 调用基类方法,避免死循环
  • setattr(self, name, value)
    • 触发时机:设置任何属性时(包括初始化赋值)
    • 作用:自定义属性赋值逻辑
  • delattr(self, name)
    • 触发时机:删除任何属性时
    • 作用:自定义属性删除逻辑

魔法方法执行顺序

  1. 访问属性 → 先触发 getattribute
  2. 若属性不存在 → 再触发 getattr
  3. 设置属性 → 触发 setattr
  4. 删除属性 → 触发 delattr

重点陷阱:无限递归

  • 场景:在 setattr 内直接给 self.属性赋值
    • 示例:矩形类重写 setattr 时,self.width = value 会再次触发 setattr
  • 解决方案
    1. 调用基类方法:super().setattr(name, value)
    2. 操作 dict 属性:self.dict[name] = value

实战案例:矩形类(支持正方形属性)

  • 需求:赋值 square 属性时,同步设置 width 和 height 为边长
  • 实现步骤
    1. init 初始化 width 和 height
    2. 重写 setattr:判断 name 为 square 时,同步赋值宽高
    3. 用 super() 或 dict 避免递归
    4. 新增 get_area 方法计算面积