Python方法中Class_name.class_variable与self.class_variable的区别及适用场景
Class_name.class_variable 和 self.class_variable 的区别详解 咱们先直击核心,再结合你的测试代码和实际场景把差异说透:
核心差异到底是什么?
简单讲就是两个访问路径的查找逻辑完全不同:
Employee.raise_amount:直接精准访问类本身存储的变量,完全不管实例有没有同名属性,也不受子类重写的影响(除非你特意写子类的类名)。self.raise_amount:走的是Python的属性查找链——先找当前实例自己的属性,如果实例没这个属性,才会去它所属的类(甚至父类链)里找对应的类变量。
为啥你的测试看起来输出一致?
你的测试代码只是打印了实例和类的变量值,但没调用apply_raise方法,所以没触发两种访问方式的差异。咱们补个测试就能看出来:
假设你用self.raise_amount写apply_raise,给emp_1设置emp_1.raise_amount=1.1后调用emp_1.apply_raise(),这时候emp_1的工资会乘以1.1(用的是实例自己的属性);但如果用Employee.raise_amount,哪怕emp_1有自己的raise_amount,工资还是会乘以类的那个值(比如1.04或者之后修改的1.2)。
什么时候用哪种方式?
选Class_name.class_variable的场景
- 必须用类的统一值:比如你要统计类的实例总数,这个计数器必须存在类上,用
Employee.total_count来更新才靠谱——要是用self.total_count,万一某个实例不小心覆盖了这个属性,统计就彻底错了。 - 不想被子类或实例干扰:如果你的类会被继承,但某个方法的逻辑必须依赖父类自己的配置,不能被子类的重写影响,就用类名访问。比如父类有个默认的超时时间,子类哪怕改了超时,父类的某个核心方法还是得用自己的默认值。
选self.class_variable的场景
- 允许实例个性化:就像你的员工例子,某个员工的涨幅可以单独设置,不影响其他同事,用
self.raise_amount就完美——实例自己设了值,调用apply_raise就用自己的涨幅,没设的话就用类的统一值。 - 支持子类扩展(多态):如果你的类是基类,希望子类能通过重写类变量来改变父类方法的行为,那必须用
self。比如:
class Manager(Employee): raise_amount = 1.1 # 经理的涨幅更高 mgr = Manager('John', 'Doe', 50000) mgr.apply_raise() # 用self的话,自动用Manager的1.1;用Employee的话还是1.04
这种情况下,self会自动适配子类实例,让父类方法能复用子类的配置,完全符合面向对象的多态设计。
一句话总结
- 要固定用类的统一值,拒绝实例/子类干扰 → 用
Class_name.class_variable; - 要支持实例自定义,或让子类能扩展逻辑 → 用
self.class_variable。
内容的提问来源于stack exchange,提问作者Hubert Kobos
相关产品推荐
相关产品推荐

