05什么是实例属性和类属性,两者的区别是什么?
文章目录
问题: 什么是实例属性和类属性,两者的区别是什么?
👇 点击展开/折叠 面试背诵模板(建议先背这个)
核心区别速览
| 维度 | 类属性 | 实例属性 |
|---|---|---|
| 定义位置 | 类体内,方法外 | __init__ 内,self.xxx |
| 归属 | 类本身 | 具体对象 |
| 内存分配 | 仅一份(类命名空间) | 每对象一份(对象 __dict__) |
| 访问方式 | 类名.属性 或 实例.属性 |
必须 实例.属性(或 self.属性) |
| 修改影响 | 影响所有未遮蔽该属性的实例 | 仅影响当前实例 |
属性查找机制与遮蔽陷阱(高频考点)
Python 属性访问遵循”就近原则”:实例.属性 会先查找实例自身的 __dict__,若未找到则向上查找类及父类的 __dict__。关键陷阱:当执行 d1.species = "新物种" 时,Python 不会修改类属性,而是在实例 __dict__ 中插入新键值对。此后 d1.species 优先命中实例属性,类属性被”遮蔽”;而 d2.species 仍指向类属性。只有通过 Dog.species = "新物种" 才能真正修改类属性。
1 | class Dog: |
可变类型类属性的共享风险(进阶陷阱)
若类属性指向可变对象(如列表、字典),通过实例调用其修改方法(如 append、update)会直接修改共享对象,影响所有实例。这与”赋值”行为不同:赋值 obj.attr = [] 是在实例上新建属性,属于遮蔽;而调用方法 obj.attr.append() 是原地修改,属于共享。
1 | class Student: |
典型应用场景与设计选择
- 类属性:存储不随实例变化的元数据(如学校名称、默认配置常量)、统计实例数量的计数器(
cls.count += 1),或预设的可选方案(如预定义的难度等级)。 - 实例属性:存储对象的唯一标识(如
name、id)、动态状态(如age、score)、以及依赖外部输入的可变数据。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 LGQ的博客!