前言
继承是面向对象编程(oop)的三大特性之一,它允许子类复用父类的属性和方法,从而实现代码的复用与扩展。在 python 中,一切类默认都是 object 的子类。本文将结合一段完整的代码示例,深入剖析 python 继承的核心概念,包括 __base__ / __bases__ 的用法、super() 调用父类方法、以及 __str__ 与 __repr__ 在继承中的重写实践。
一、继承的基本概念
在 python 中,继承的语法非常简洁:
class 父类:
pass
class 子类(父类):
pass- 父类(基类、超类):被继承的类
- 子类:继承父类的类
我们可以通过两个特殊属性来查看类的父类信息:
| 属性 | 说明 |
|---|---|
类名.__base__ | 获取单个父类 |
类名.__bases__ | 获取父类元组 |
class person(object):
pass
print(person.__base__) # <class 'object'>
print(person.__bases__) # (<class 'object'>,)二、从简单继承开始
我们先定义一个 person 类,包含姓名和年龄属性,以及 get_info 方法:
class person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def get_info(self):
return f"name:{self.name}, age:{self.age}"person 类默认继承自 object,拥有所有对象的基本行为。
三、子类继承与super()调用父类
现在定义一个 superperson 子类,在父类的基础上增加 skill 属性:
class superperson(person):
def __init__(self, name, age, skill):
super().__init__(name, age) # 调用父类的 __init__
self.skill = skill
def get_info(self):
return f"{super().get_info()}, skill:{self.skill}"这里的关键是 super():
super() 返回一个代理对象,用于调用父类的方法
super().__init__(name, age) 调用了父类 person 的构造函数,完成 name 和 age 的初始化super().get_info() 调用了父类的 get_info 方法,在此基础上追加子类的 skill 信息
为什么要用 super()? 在单继承中,直接使用父类名调用(如 person.__init__(self, name, age))也可以工作。但在多重继承中,super() 会遵循 mro(方法解析顺序) 规则,避免重复调用和钻石继承问题。因此,推荐始终使用 super(),即使是在单继承场景中。
四、重写__str__与__repr__
__str__ 和 __repr__ 是 python 中用于定义对象字符串表示的两个魔术方法:
| 方法 | 面向对象 | 调用时机 |
|---|---|---|
__str__ | 最终用户 | print()、str()、format() |
__repr__ | 开发者 | repr()、控制台直接输出、调试 |
重要规则: 如果没有定义 __str__,python 会回退调用 __repr__。
父类中定义
class person(object):
def __str__(self):
return "person"
def __repr__(self):
return "person()"测试输出:
p1 = person("马克思", 20)
print(p1, [p1]) # person [person()]
print(p1)调用__str__,输出person- 列表展示时调用
__repr__,输出person()
子类中重写并复用父类
class superperson(person):
def __str__(self):
return f"super{super().__str__()}"
def __repr__(self):
return f"super{super().__repr__()}"这里通过 super() 调用了父类的 __str__ 和 __repr__,并在其基础上添加了 "super" 前缀:
sp1 = superperson("绿巨人", 30, "变身")
print(sp1, [sp1]) # superperson [superperson()]这样做的好处是:
- 复用父类逻辑,避免重复编码
- 保持一致性,子类的字符串表示在父类基础上扩展
- 易于维护,父类逻辑变更时子类自动同步
五、完整代码回顾
class person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "person"
def __repr__(self):
return "person()"
def get_info(self):
return f"name:{self.name}, age:{self.age}"
class superperson(person):
def __init__(self, name, age, skill):
super().__init__(name, age)
self.skill = skill
def __str__(self):
return f"super{super().__str__()}"
def __repr__(self):
return f"super{super().__repr__()}"
def get_info(self):
return f"{super().get_info()}, skill:{self.skill}"六、总结
| 知识点 | 要点 |
|---|---|
__base__ / __bases__ | 查看类的父类信息 |
super() | 调用父类方法,支持 mro,推荐优先使用 |
__str__ vs __repr__ | __str__ 面向用户,__repr__ 面向开发者 |
| 继承中的方法重写 | 使用 super() 复用父类逻辑,保持代码 dry |
继承让代码复用变得简单,而 super() 则是让继承变得优雅的关键工具。掌握这些基础,你就能在 python 面向对象编程中游刃有余。
到此这篇关于python 继承深度解析 从 __base__ 到 super() 的完整实践指南的文章就介绍到这了,更多相关python __base__ 到 super() 内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论