在子类中重写父类的类变量,核心是给子类定义同名的类变量(或通过子类名动态赋值),让子类拥有独立的类变量,不再共享父类的同名变量。下面分「静态重写」「动态重写」两种场景,结合示例讲透具体操作、效果和避坑点。
一、核心原理
父类的类变量会被子类继承,若子类未定义同名变量,访问子类 / 子类实例的该变量时,会读取父类的;若子类定义了同名类变量(重写),子类会在自己的命名空间中创建独立变量,与父类解耦,后续修改子类的该变量不会影响父类。
二、场景 1:静态重写(定义子类时直接声明)
这是最常用的方式 —— 在子类定义时,直接声明与父类同名的类变量,完成重写。
示例:基础静态重写
python
运行
class Parent: # 父类类变量 brand = "父类默认品牌" max_count = 10 class Child(Parent): # 重写:子类声明同名类变量,覆盖父类的 brand = "子类定制品牌" # 可只重写部分变量(如只重写brand,保留max_count) # 验证重写效果 print(Parent.brand) # 输出:父类默认品牌(父类不变) print(Child.brand) # 输出:子类定制品牌(子类用自己的) print(Child.max_count) # 输出:10(未重写,仍继承父类) # 修改子类重写后的变量,不影响父类 Child.brand = "子类修改后的品牌" print(Child.brand) # 输出:子类修改后的品牌 print(Parent.brand) # 输出:父类默认品牌(不受影响)示例:重写可变类型类变量
若父类类变量是列表、字典等可变类型,子类重写时需赋值新的可变对象,而非修改父类对象的内部元素:
python
运行
class Parent: # 父类可变类变量 items = [1, 2, 3] class Child(Parent): # 重写:赋值新的列表(子类独立变量) items = [10, 20, 30] # 验证 print(Parent.items) # 输出:[1,2,3](父类不变) print(Child.items) # 输出:[10,20,30](子类自己的) # 修改子类变量的内部元素,仅影响子类 Child.items.append(40) print(Child.items) # 输出:[10,20,30,40] print(Parent.items) # 输出:[1,2,3](父类不受影响)三、场景 2:动态重写(运行时赋值)
若需要在程序运行时(而非定义子类时)重写父类类变量,可通过「子类名。变量名 = 新值」动态赋值,效果与静态重写一致。
示例:动态重写类变量
python
运行
class Parent: version = "1.0" config = {"mode": "normal"} class Child(Parent): # 初始未重写,继承父类的version和config pass # 运行时动态重写单个变量 Child.version = "2.0" print(Child.version) # 输出:2.0(子类独立变量) print(Parent.version) # 输出:1.0(父类不变) # 动态重写可变类型变量(赋值新对象) Child.config = {"mode": "debug", "timeout": 10} print(Child.config) # 输出:{'mode': 'debug', 'timeout': 10} print(Parent.config) # 输出:{'mode': 'normal'}(父类不变)四、场景 3:在子类方法中重写 / 修改重写后的类变量
子类重写类变量后,在子类的实例方法 / 类方法中修改时,需用「子类名。变量名」,而非self(self赋值会创建实例变量)。
示例:子类方法中操作重写后的类变量
python
运行
class Parent: count = 0 class Child(Parent): # 静态重写类变量 count = 100 def add_count(self): # 正确:修改子类自己的类变量 Child.count += 1 def wrong_add(self): # 错误:self.count +=1 → 给实例新增count变量,而非修改类变量 self.count += 1 # 验证正确操作 c = Child() c.add_count() print(Child.count) # 输出:101(子类类变量已改) print(c.count) # 输出:101(读子类类变量) # 验证错误操作 c.wrong_add() print(c.count) # 输出:102(实例变量) print(Child.count) # 输出:101(子类类变量未变)五、重写的避坑点
- 不要通过实例重写类变量:
子类实例.变量名 = 新值只会给实例新增同名实例变量,不会重写子类的类变量;python
运行
c = Child() c.brand = "实例临时值" print(c.brand) # 输出:实例临时值(实例变量) print(Child.brand) # 输出:子类定制品牌(子类类变量未变) - 可变类型变量避免 “修改父类元素”:若子类未重写,直接修改父类可变变量的内部元素(如
Child.items.append(4)),会影响父类和所有未重写的子类,这不是 “重写”,而是 “修改父类变量”; - 不要滥用双下划线命名:父类类变量若用双下划线开头(如
__var),会触发名称改写(变成_Parent__var),子类需用_Parent__var才能访问,重写时易出错,非必要不要用。
六、重写 vs 继承:核心对比
| 操作 | 效果 | 适用场景 |
|---|---|---|
| 子类不重写父类变量 | 子类共享父类的变量,父类修改会同步影响子类 | 子类需继承父类的全局配置 |
| 子类重写父类变量 | 子类拥有独立变量,与父类解耦 | 子类需要定制化配置 |
总结:子类重写父类类变量的 3 条核心规则
- 静态重写:定义子类时直接声明同名类变量;
- 动态重写:运行时通过
子类名.变量名 = 新值赋值; - 可变类型:重写时必须赋值新的可变对象(如
[]/{}),而非修改父类对象的内部元素。
只要遵循「子类名绑定新值」的原则,就能实现类变量的重写,让子类拥有独立的类级属性。
https://avg.163.com/topic/detail/8089550
https://avg.163.com/topic/detail/8089584
https://avg.163.com/topic/detail/8089628
https://avg.163.com/topic/detail/8089740
https://avg.163.com/topic/detail/8089361
https://avg.163.com/topic/detail/8089549
https://avg.163.com/topic/detail/8089586
https://avg.163.com/topic/detail/8089629
https://avg.163.com/topic/detail/8089743
https://avg.163.com/topic/detail/8089359
https://avg.163.com/topic/detail/8089548
https://avg.163.com/topic/detail/8089623
https://avg.163.com/topic/detail/8089742
https://avg.163.com/topic/detail/8089547
https://avg.163.com/topic/detail/8089741
https://avg.163.com/topic/detail/8089355
https://avg.163.com/topic/detail/8089540
https://avg.163.com/topic/detail/8089621
https://avg.163.com/topic/detail/8089738
https://avg.163.com/topic/detail/8089368
https://avg.163.com/topic/detail/8089542
https://avg.163.com/topic/detail/8089590
https://avg.163.com/topic/detail/8089625
https://avg.163.com/topic/detail/8089739
https://avg.163.com/topic/detail/8089546
https://avg.163.com/topic/detail/8089588
https://avg.163.com/topic/detail/8089619
https://avg.163.com/topic/detail/8089545
https://avg.163.com/topic/detail/8089587
https://avg.163.com/topic/detail/8089626
https://avg.163.com/topic/detail/8089735
https://avg.163.com/topic/detail/8089544
https://avg.163.com/topic/detail/8089585
https://avg.163.com/topic/detail/8089624
https://avg.163.com/topic/detail/8089736
https://avg.163.com/topic/detail/8089364
https://avg.163.com/topic/detail/8089543
https://avg.163.com/topic/detail/8089734
https://avg.163.com/topic/detail/8089541
https://avg.163.com/topic/detail/8089620
https://avg.163.com/topic/detail/8089539
https://avg.163.com/topic/detail/8089580
https://avg.163.com/topic/detail/8089618
https://avg.163.com/topic/detail/8089731
https://avg.163.com/topic/detail/8089358
https://avg.163.com/topic/detail/8089538
https://avg.163.com/topic/detail/8089574
https://avg.163.com/topic/detail/8089617
https://avg.163.com/topic/detail/8089732
https://avg.163.com/topic/detail/8089351
https://avg.163.com/topic/detail/8089537
https://avg.163.com/topic/detail/8089573
https://avg.163.com/topic/detail/8089616
https://avg.163.com/topic/detail/8089730
https://avg.163.com/topic/detail/8089349
https://avg.163.com/topic/detail/8089581
https://avg.163.com/topic/detail/8089728
https://avg.163.com/topic/detail/8089348
https://avg.163.com/topic/detail/8089535
https://avg.163.com/topic/detail/8089579
https://avg.163.com/topic/detail/8089613
https://avg.163.com/topic/detail/8089729
https://avg.163.com/topic/detail/8089346
https://avg.163.com/topic/detail/8089720
https://avg.163.com/topic/detail/8089345
https://avg.163.com/topic/detail/8089533
https://avg.163.com/topic/detail/8089342
https://avg.163.com/topic/detail/8089725
https://avg.163.com/topic/detail/8089532
https://avg.163.com/topic/detail/8089576
https://avg.163.com/topic/detail/8089717
https://avg.163.com/topic/detail/8089347
https://avg.163.com/topic/detail/8089575
https://avg.163.com/topic/detail/8089722
https://avg.163.com/topic/detail/8089344
https://avg.163.com/topic/detail/8089530
https://avg.163.com/topic/detail/8089572
https://avg.163.com/topic/detail/8089607
https://avg.163.com/topic/detail/8089727
https://avg.163.com/topic/detail/8089343
https://avg.163.com/topic/detail/8089528
https://avg.163.com/topic/detail/8089571
https://avg.163.com/topic/detail/8089602
https://avg.163.com/topic/detail/8089341
https://avg.163.com/topic/detail/8089605
https://avg.163.com/topic/detail/8089713
https://avg.163.com/topic/detail/8089336
https://avg.163.com/topic/detail/8089340
https://avg.163.com/topic/detail/8089567
https://avg.163.com/topic/detail/8089569
https://avg.163.com/topic/detail/8089614
https://avg.163.com/topic/detail/8089565
https://avg.163.com/topic/detail/8089719
https://avg.163.com/topic/detail/8089612
https://avg.163.com/topic/detail/8089337
https://avg.163.com/topic/detail/8089527
https://avg.163.com/topic/detail/8089529
https://avg.163.com/topic/detail/8089608
https://avg.163.com/topic/detail/8089563
https://avg.163.com/topic/detail/8089715
https://avg.163.com/topic/detail/8089610
https://avg.163.com/topic/detail/8089330
https://avg.163.com/topic/detail/8089597
https://avg.163.com/topic/detail/8089708
https://avg.163.com/topic/detail/8089333
https://avg.163.com/topic/detail/8089566
https://avg.163.com/topic/detail/8089604
https://avg.163.com/topic/detail/8089338
https://avg.163.com/topic/detail/8089335
https://avg.163.com/topic/detail/8089524
https://avg.163.com/topic/detail/8089521
https://avg.163.com/topic/detail/8089564
https://avg.163.com/topic/detail/8089606
https://avg.163.com/topic/detail/8089601
https://avg.163.com/topic/detail/8089714
https://avg.163.com/topic/detail/8089709
https://avg.163.com/topic/detail/8089519
https://avg.163.com/topic/detail/8089520
https://avg.163.com/topic/detail/8089559
https://avg.163.com/topic/detail/8089560
https://avg.163.com/topic/detail/8089598
https://avg.163.com/topic/detail/8089724
https://avg.163.com/topic/detail/8089721
https://avg.163.com/topic/detail/8089328
https://avg.163.com/topic/detail/8089518
https://avg.163.com/topic/detail/8089558
https://avg.163.com/topic/detail/8089596
https://avg.163.com/topic/detail/8089710