类属性属于类、被所有实例共享,实例属性属于 对象 、各实例独立;类属性定义在class 内方法外,实例属性通过 self 在__init__中定义;避免用可变对象作类属性默认值。

类属性和实例属性在 python 中作用不同,关键 区别 在于归属对象和生命周期:类属性属于类本身,所有实例共享;实例属性属于具体对象,每个实例独立拥有。
类属性:定义在类内部、方法外部的变量
类属性在类定义时创建,被该类所有实例共同引用。修改类属性会影响所有未覆盖该属性的实例。
- 适合存储 常量 、配置项、计数器等全局性数据,比如 类名、版本号、默认超时时间
- 定义方式:直接写在 class 代码块里,不在任何 def 下,例如
count = 0 - 访问方式:可通过类名(
MyClass.count)或实例(obj.count)读取;但用实例修改会 ** 意外创建同名实例属性 **,不再影响类属性
实例属性:在__init__或实例方法中通过 self 绑定的变量
实例属性在对象创建(调用__init__)时生成,每个实例一份独立副本,互不干扰。
- 适合保存对象独有的状态信息,比如 用户 ID、缓存数据、临时标记
- 定义方式:必须用
self.xxx = value形式 ,常见于__init__中 - 访问方式:只能通过实例(
obj.name),类名直接访问会报错(除非类也定义了同名类属性)
常见混淆点与避坑建议
很多 bug 源于误把可变类属性当实例属性用,尤其列表、字典这类可变对象。
立即学习“Python 免费学习笔记(深入)”;
- 不要用可变对象做类属性默认值,例如
data = []—— 所有实例会共用同一个列表 - 需要默认空列表?在
__init__里写self.data = [] - 想统计实例数量?类属性
count在__init__中自增,但记得用MyClass.count += 1而非self.count += 1(后者会新建实例属性)
典型使用场景对比
一个实际例子:设计一个连接池管理类
- 类属性:
max_connections = 10(全局限制)、_pool = [](共享连接池容器) - 实例属性:
self.id = next_id()(每个连接唯一 ID)、self.is_busy = False(当前连接状态) - 这样既保证资源统一调度,又保留个体差异