python中的super关键字_Python super

本文通过实例详细解析Python的super关键字,介绍如何利用super调用父类构造函数及解决多重继承问题,避免重复调用和MRO问题。
摘要由CSDN通过智能技术生成

Python super教程

super 是用来解决

super() 函数是用于调用父类(超类)的一个方法,super 不仅仅可以调用父类的

Python super详解

语法

super(type[, object-or-type])

说明

其中,type 参数一般是我们需要调用的类,object-or-type 参数一般是 self。

案例

Python super解决多重继承问题

使用 super 解决多重继承问题

print("嗨客网(www.haicoder.net)")

class Person:

def __init__(self, name, age):

self.name = name

self.age = age

class Job:

def __init__(self, job):

self.__job = job

def setjob(self, val):

self.__job = val

def getjob(self):

return self.__job

job = property(getjob, setjob)

class Teacher(Person, Job):

def summary_info(self):

print("Name =", self.name, "Age =", self.age)

def info(self):

print("Name =", self.name, "Age =", self.age, "Job =", self.job)

teacher = Teacher("HaiCoder", 18)

teacher.summary_info()

程序运行后,控制台输出如下:

117522260e4c01526bb720890734d976.png

我们定义了一个 Person 类,Person 类有两个属性,分别为 name 和 age 和一个构造函数 。接着,我们又定义了一个 Job 类,Job 类有一个 job 属性。

最后,我们定义了一个 Teacher 类,Teacher 类继承自 Person 类和 Job 类,并且自己有一个 summary_info 函数和一个 info 函数,用于输出 Teacher 类的实例信息。

Teacher 类继承自 Person 类和 Job 类,因此 Teacher 类会同时继承了 Person 类的构造函数和 Job 类的构造函数,但因此 Person 类在前面,因此,默认实例化 Teacher 类时,使用的是 Person 类的构造函数。

所以,在实例化 Teacher 类时,需要传入两个参数,用来初始化 name 和 age 属性的值。此时,我们调用 summary_info 函数,程序没有问题,正常输出了 name 和 age 属性的值。我们将程序修改如下:

print("嗨客网(www.haicoder.net)")

class Person:

def __init__(self, name, age):

self.name = name

self.age = age

class Job:

def __init__(self, job):

self.__job = job

def setjob(self, val):

self.__job = val

def getjob(self):

return self.__job

job = property(getjob, setjob)

class Teacher(Person, Job):

def summary_info(self):

print("Name =", self.name, "Age =", self.age)

def info(self):

print("Name =", self.name, "Age =", self.age, "Job =", self.job)

teacher = Teacher("HaiCoder", 18)

teacher.info()

程序运行后,控制台输出如下:

f0bdd920fe901bd2fb3ec8ede675d405.png

此时,再次运行程序,程序报错,因此我们没有初始化从 Job 类继承来的 job 属性。我们再次将程序修改如下:

print("嗨客网(www.haicoder.net)")

class Person:

def __init__(self, name, age):

self.name = name

self.age = age

class Job:

def __init__(self, job):

self.__job = job

def setjob(self, val):

self.__job = val

def getjob(self):

return self.__job

job = property(getjob, setjob)

class Teacher(Person, Job):

def summary_info(self):

print("Name =", self.name, "Age =", self.age)

def info(self):

print("Name =", self.name, "Age =", self.age, "Job =", self.job)

teacher = Teacher("HaiCoder", 18)

teacher.job = "teach"

teacher.info()

程序运行后,控制台输出如下:

30aece1b9f3ed8d9e49f1419dd74a697.png

此时,再次运行程序,程序运行正常,因此我们手动初始化了从 Job 类继承来的 job 属性。但这样,程序就有弊端,如果我们忘记了手动初始化继承的属性,那么程序就会报错,我们期望能再构造函数里面初始化对应的值,

我们将程序修改如下:

print("嗨客网(www.haicoder.net)")

class Person:

def __init__(self, name, age):

self.name = name

self.age = age

class Job:

def __init__(self, job):

self.__job = job

def setjob(self, val):

self.__job = val

def getjob(self):

return self.__job

job = property(getjob, setjob)

class Teacher(Person, Job):

def __init__(self, name, age, job):

self.name = name

self.age = age

self.job = job

def info(self):

print("Name =", self.name, "Age =", self.age, "Job =", self.job)

teacher = Teacher("HaiCoder", 18, "Teach")

teacher.info()

程序运行后,控制台输出如下:

6afab3fc342151e6d2f49243c36d410c.png

我们在子类 Teacher 里面定义了构造函数 __init__,该函数传入三个属性值,我们手动使用赋值的形式,初始化从父类继承来的三个属性值,这样可以解决问题,但是,如果,我们的构造函数不是简简单单的赋值逻辑,而是有一套很复杂的初始化逻辑,

那么我们在子类 Teacher 的构造函数里面,同样需要实现一套复杂的逻辑,因此,我们期望,在子类 Teacher 里,可以直接调用父类的构造函数,我们将程序修改如下:

print("嗨客网(www.haicoder.net)")

class Person:

def __init__(self, name, age):

self.name = name

self.age = age

class Job:

def __init__(self, job):

self.__job = job

def setjob(self, val):

self.__job = val

def getjob(self):

return self.__job

job = property(getjob, setjob)

class Teacher(Person, Job):

def __init__(self, name, age, job):

Person.__init__(self, name, age)

Job.__init__(self, job)

def info(self):

print("Name =", self.name, "Age =", self.age, "Job =", self.job)

teacher = Teacher("HaiCoder", 18, "Teach")

teacher.info()

程序运行后,控制台输出如下:

6c7d6d6d1c2a48c58f831905ad7f392b.png

我们在 Teacher 类的构造函数里面,通过显式的调用父类的类名 Person 和 Job 的构造函数的方式来初始化了父类的属性,这样,虽然可以解决问题,但不太优雅,Python 提供了 super 函数,专门用来解决子类调用父类的方法,我们将程序修改如下:

print("嗨客网(www.haicoder.net)")

class Person:

def __init__(self, name, age):

self.name = name

self.age = age

class Job:

def __init__(self, job):

self.__job = job

def setjob(self, val):

self.__job = val

def getjob(self):

return self.__job

job = property(getjob, setjob)

class Teacher(Person, Job):

def __init__(self, name, age, job):

super().__init__(name, age)

Job.__init__(self, job)

def info(self):

print("Name =", self.name, "Age =", self.age, "Job =", self.job)

teacher = Teacher("HaiCoder", 18, "Teach")

teacher.info()

程序运行后,控制台输出如下:

375fd8f225ca8a9bf126c0502fe4e94b.png

我们通过 super 实现了调用父类的构造函数,这里的 super 指的就是 Person 类,因此虽然我们的 Teacher 继承了 Person 和 Job,但 Person 是第一个,因此,这里的 suprt 指的就是 Person。

super调用父类实例方法

使用 super 解决多重继承问题

print("嗨客网(www.haicoder.net)")

class Animal:

def eat(self):

print("I like eat anything")

def sleep(self):

print("I need sleep for 15 hours a day")

class Cat(Animal):

def eat(self):

print("I am a cat, and i just like eat finish")

def eat_delicious(self):

print("when i was a child")

self.eat()

print("when i grown up")

super().eat()

cat = Cat()

cat.eat_delicious()

cat.sleep()

程序运行后,控制台输出如下:

b92e170695eaae3abee4567427b360cd.png

我们在 eat_delicious 方法中,通过 super 调用了父类被覆盖的 eat 实例方法。

Python super教程总结

super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

super() 函数是用于调用父类(超类)的一个方法,super 不仅仅可以调用父类的构造函数,还可以调用父类的成员函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值