Python类继承两种实现方式的差异及优劣势对比
问题1:两种实现方式的核心差异
两种写法的核心差异是Teacher实例属性的完备时机和类的使用约束不同:
- 第一种写法重写了子类的
__init__方法,要求创建Teacher实例时必须传入schoolgrade参数,实例完成初始化的那一刻就自带所有固有属性(firstname/lastname/schoolclass),不存在属性缺失的中间状态。 - 第二种写法没有重写
__init__,创建Teacher实例时只需要传姓名参数,schoolclass属性必须在实例创建完成后,手动调用schoolspec方法才会被绑定到实例上,在调用方法前实例是属性不完备的状态。
问题2:两种方式的优劣势对比
第一种(重写__init__主动调用父类初始化)
优势:
- 实例初始化即完备,不会出现后续访问属性时报
AttributeError的问题,稳定性更高 - 类的入参契约清晰,使用方只要看
__init__方法就能明确创建实例需要的所有参数,使用成本低 - 符合面向对象封装原则:年级是教师的固有属性,应该在对象创建阶段就完成赋值,不需要额外的手动操作
- 扩展性更强:如果后续要对
schoolgrade做参数合法性校验,直接在__init__里加逻辑就可以,所有实例都会触发校验,不会出现漏校验的情况
劣势:
- 代码量稍多,新增子类属性时需要记得调用父类的初始化方法,新手容易漏写导致父类属性未初始化(现在更推荐用
super().__init__(fname, lname)替代硬编码父类名的调用方式,更易维护)
第二种(不重写__init__,单独新增属性设置方法)
优势:
- 写法简单,不需要处理父类初始化的调用逻辑,新手不容易在继承调用环节出错
- 适合
schoolclass属于可选、可动态修改的非固有属性场景,灵活度更高
劣势:
- 实例存在属性不完备的中间状态,一旦使用方忘记调用
schoolspec方法,后续访问schoolclass就会直接报错,调试成本高 - 类的使用契约不清晰,其他开发者使用这个类时,无法从初始化方法判断出还需要额外调用方法才能补全属性,很容易踩坑
- 不利于统一做参数校验,如果多个地方调用
schoolspec,校验逻辑要重复写,也容易出现漏校验的非法属性值
内容的提问来源于stack exchange,提问作者BertHobe
相关产品推荐
相关产品推荐

