[Python3]在子类中调用父类的方法

本文介绍了Python中子类如何调用父类方法的两种方式:指名道姓调用和使用super()函数。通过具体实例说明了这两种方法的区别及super()如何在多重继承中按MRO顺序工作。

在子类派生出的新方法中,往往需要重用父类的方法,有两种方式实现。

方式一:指名道姓,即父类名.父类方法()

方式二:super()

class Vehicle:      # 定义交通工具类
    Country = 'China'
    def __init__(self, name, speed, load, power):
        self.name = name
        self.speed = speed
        self.load = load
        self.power = power

    def run(self):
        print('开动啦')


class Subway(Vehicle):
    def __init__(self, name, speed, load, power, line):
        # super().__init__(name, speed, load, power)  # super()等同于super(Subway,self)
        Vehicle.__init__(self, name, speed, load, power)  # 指名道姓方式
        self.line = line

    def run(self):
        print('地铁%s号线开动啦' % self.line)
        Vehicle.run(self)

s = Subway('中国地铁', '350km/h', '1000人/车厢', '电', 13)
s.run()

这两种方式的区别是:方式一是跟继承没有关系的,而方式二的super()是依赖继承的,并且即使没有直接继承关系,super仍然会按照mro继续往后查找。

#A没有继承B,但是A内super会基于C.mro()继续往后找
class A:
    def test(self):
        super().test()
class B:
    def test(self):
        print('from B')
class C(A,B):
    pass

c=C()
c.test() #打印结果:from B


print(C.mro())
#[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

 

<think>我们正在讨论Python子类如何调用父类方法或构造函数,特别是使用super()的方式。根据引用[1][2][4],super()是推荐的方式,尤其是在多继承的情况下,因为它遵循方法解析顺序(MRO),避免直接使用父类名称调用可能带来的问题。引用[4]还提到,在调用第一个父类方法时,可以使用super(),而调用其他父类方法时,可能需要使用父类名称显式调用(未绑定方法)并传递self。用户问题:请问Python子类调用父类方法super()使用方式因此,我们需要详细解释super()的使用方式,包括在单继承和多继承中的用法。注意:在Python3中,super()可以不带参数使用(在类的方法内部),它会自动绑定当前类和实例。回答结构:1.单继承情况下的super()使用2.多继承情况下的super()使用(注意方法解析顺序MRO)3.在构造函数中的使用(__init__)4.在普通方法中的使用5.注意事项同时,根据引用[3],如果子类重写了__init__,那么父类的__init__不会自动调用,需要使用super()来调用。生成相关问题:1.在多重继承中,super()是如何确定调用顺序的?2.除了super(),还有哪些调用父类方法的方式?3.在子类调用父类方法时,如何避免重复调用?4.使用super()时常见的错误有哪些?开始回答:</think>### Python子类调用父类方法:`super()`使用详解 在Python中,子类调用父类方法主要使用`super()`函数,这是一种安全且支持多继承的机制。以下是具体使用方式: #### 1. **单继承中的基本用法** ```python class Parent: def __init__(self, name): self.name = name def greet(self): print(f"Hello, I&#39;m {self.name}") class Child(Parent): def __init__(self, name, age): super().__init__(name) # 调用父类构造函数 self.age = age def greet(self): super().greet() # 调用父类方法 print(f"I&#39;m {self.age} years old") # 使用 child = Child("Alice", 10) child.greet() ``` **输出**: ``` Hello, I&#39;m Alice I&#39;m 10 years old ``` - `super().__init__(name)`:调用父类构造函数初始化`name` - `super().greet()`:调用父类的`greet()`方法[^2][^4] #### 2. **多继承中的用法** ```python class Father: def __init__(self): self.father_gene = "XY" def show(self): print("Father&#39;s method") class Mother: def __init__(self): self.mother_gene = "XX" def show(self): print("Mother&#39;s method") class Child(Father, Mother): def __init__(self): super().__init__() # 调用第一个父类(Father)的构造方法 # 显式调用其他父类 Mother.__init__(self) def show(self): super().show() # 按MRO顺序调用(Father.show) Mother.show(self) # 显式调用Mother的方法 # 查看方法解析顺序(MRO) print(Child.mro()) # 输出: [Child, Father, Mother, object] # 使用 child = Child() child.show() ``` **输出**: ``` Father&#39;s method Mother&#39;s method ``` - **MRO规则**:`super()`按`__mro__`列表顺序调用(此处优先调用`Father.show()`)[^4] - **显式调用**:对其他父类需用`父类名.方法(self)`[^4] #### 3. **在方法重写中保留父类逻辑** ```python class User: def save(self): print("数据保存到数据库") class Admin(User): def save(self): print("执行权限检查") # 子类新增逻辑 super().save() # 保留父类核心逻辑 admin = Admin() admin.save() ``` **输出**: ``` 执行权限检查 数据保存到数据库 ``` ### 注意事项 1. **Python 2/3差异**: - Python 3:`super()`无需参数(推荐) - Python 2:需显式指定`super(子类名, self)` 2. **避免循环调用**: ```python class A: def run(self): print("A") class B(A): def run(self): print("B") super().run() # 正确:调用父类A.run() # 错误示例(无限递归): class C(A): def run(self): print("C") self.run() # 错误!应使用super().run() ``` 3. **多继承原则**: - 所有父类构造函数参数需兼容 - 使用`super()`时,确保各父类也通过`super()`传递调用[^4] > **关键点**:`super()`动态绑定父类方法,遵循MRO顺序,在多继承中比直接使用父类名更安全[^1][^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值