Python 入门学习笔记(六)
一、类的继承(子类、父类)
Python是一门面向对象的编程语言,支持类继承。新的类称为子类Subclass,被继承的类称为父类、基类或者超类。子类继承父类后,就拥有父类的所有特性。
五个内容模块
0):定义子类
1):继承父类初始化过程中的参数
2):调用父类的__init__方法,定义新增子类属性
3):直接调用父类属性方法
4):重写父类属性方法
5):强制调用父类私有属性方法
(0)定义子类、
(1)继承父类初始化过程中的参数、
(2)调用父类的__init__方法,定义新增子类属性
定义子类的方法
定义: class 子类名(父类名):
情况1:如果子类有新增的属性,那么需要在子类__init__方法中,调用父类的__init__ 指的是需要在子类属性__init__中调用,father.__init__
,再自定义新增的子类。也可以用super().__init__()
方法继承父类的属性
情况2:如果子类没有新增的属性,子类不需要写__init__方法 使用: 对象名 = 子类名(参数)
#读取数据
def get_coach_data(filename):
with open(filename) as f:
line = f.readline()
return line.strip().split(',')
#定义父类
class Athlete:
def __init__(self,a_name,a_dob=None,a_times=[]):
self.name = a_name
self.dob = a_dob
self.times = a_times
def top3(self):
return sorted(set([self.sanitize(t) for t in self.times]))[0:3]
def sanitize(self,time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return (time_string)
(mins,secs) = time_string.split(splitter)
return (mins+'.'+secs)
#定义子类(橄榄球运送员类)
class Rugby(Athlete):
def __init__(self,a_name,a_bod,a_squat,a_times):
#调用父类__init__
Athlete.__init__(self,a_name,a_bod,a_times)
#深蹲次数!!!!!新增的子类属性
self.squat = a_squat
# 继承后下面两个函数就在Rugby类中,只是看不到而已
# def top3(self):
# return sorted(set([self.sanitize(t) for t in self.times]))[0:3]
# def sanitize(self,time_string):
# if '-' in time_string:
# splitter = '-'
# elif ':' in time_string:
# splitter = ':'
# else:
# return (time_string)
# (mins,secs) = time_string.split(splitter)
# return (mins+'.'+secs)
(3)调用父类属性方法
loren = get_coach_data('mywork/loren.txt')
rugby = Rugby(loren.pop(0),loren.pop(0),loren.pop(0),loren)
print('姓名:%s,生日:%s,深蹲:%s个,最块的3次成绩:%s' %(rugby.name,rugby.dob,rugby.squat,rugby.top3()))
#OUTPUT
姓名:2011-11-3,生日:270,深蹲:3.59个,最块的3次成绩:['3.11', '3.23', '4.10']
(4)重写父类属性方法
子类方法与父类方法完全相同,子类若重写了父类的方法,则子类对象调用方法时就是调用的自己类中重新的方法。
具体方法:直接定义一个方法函数名称与父类方法函数一致,重写方法函数中具体的内容即可。
class OtherAthlete(Athlete):
def __init__(self,a_name,a_bod,a_squat,a_times):
Athlete.__init__(self,a_name,a_bod,a_times)
self.squat = a_squat
def top3(self):
return sorted([self.sanitize(t) for t in self.times])[0:3]
mark = get_coach_data('mywork/mark.txt')
mark = OtherAthlete(mark.pop(0),mark.pop(0),mark.pop(0),mark)
print('姓名:%s,生日:%s,深蹲:%s个,最快的3次成绩:%s' %(mark.name,mark.dob,mark.squat,mark.top3()))
#OUTPUT
姓名:mark,生日:2010-2-4,深蹲:300个,最快的3次成绩:['3.11', '3.11', '3.23']
(5)强制调用父类私有方法
如果父类的方法是私有方法,如 def __action(self) 这样的话再去调用就提示没有这个方法,其实编译器是把这个方法的名字改成了 _Father__action(),如果强制调用,可以这样
class Father():
def __action(self): # 父类的私有方法
print('调用父类的方法')
class Son(Father):
def action(self):
super()._Father__action()
son=Son()
son.action()
#OUTPUT
调用父类的方法
二、多态性
多态的作用:让具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容(功能)的函数。
多态的特点:
1、只关心对象的实例方法是否同名,不关心对象所属的类型;
2、对象所属的类之间,继承关系可有可无;
3、多态的好处可以增加代码的外部调用灵活度,让代码更加通用,兼容性比较强;
4、多态是调用方法的技巧,不会影响到类的内部设计。
(1)对象所属的类之间没有继承关系时
调用同一个函数fly(), 传入不同的参数(对象),可以达成不同的功能
class Duck(object): # 鸭子类
def fly(self):
print("鸭子沿着地面飞起来了")
class Swan(object): # 天鹅类
def fly(self):
print("天鹅在空中翱翔")
class Plane(object): # 飞机类
def fly(self):
print("飞机隆隆地起飞了")
def fly(obj): # 实现飞的功能函数
obj.fly()
duck = Duck()
fly(duck)
swan = Swan()
fly(swan)
plane = Plane()
fly(plane)
#OUTPUT
鸭子沿着地面飞起来了
天鹅在空中翱翔
飞机隆隆地起飞了
(2)对象所属的类之间有继承关系(应用更广)
class gradapa(object):
def __init__(self,money):
self.money = money
def p(self):
print("this is gradapa")
class father(gradapa):
def __init__(self,money,job):
#用super()方法继承父类的属性
super().__init__(money)
self.job = job
def p(self):
print("this is father,我重写了父类的方法")
class mother(gradapa):
def __init__(self, money, job):
super().__init__(money)
self.job = job
def p(self):
print("this is mother,我重写了父类的方法")
return 100
#定义一个函数,函数调用类中的p()方法
def fc(obj):
obj.p()
gradapa1 = gradapa(3000)
father1 = father(2000,"工人")
mother1 = mother(1000,"老师")
fc(gradapa1) #这里的多态性体现是向同一个函数,传递不同参数后,可以实现不同功能.
fc(father1)
print(fc(mother1))
#OUTPUT
this is gradapa
this is father,我重写了父类的方法
this is mother,我重写了父类的方法
100
三、多继承
一个子类可以继承多个父类是多继承
一层层继承下去是多重继承
class Father():
def talk(self):
print("---爸爸的表达能力---")
class Mather():
def smart(self):
print("---妈妈聪明的头脑---")
class Child(Father,Mather):
pass
child1 = Child()
child1.talk()
child1.smart()
#OUTPUT
---爸爸的表达能力---
---妈妈聪明的头脑---
四、导入类模块
import sys
导入sys模块 sys.path.append(‘work’)
将模块athlete.py添加到模块搜索路径
from athlete import *
导入athlete模块,使用athlete模块下的所有代码
import sys
sys.path.append('mywork')
# import athlete
# print(dir(athlete))
from athlete import *
如果有一个模块mymodule.py中也包含get_coach_data函数,该怎么区分这两个函数呢?
文件夹目录为:
work/p1/get_coach_data.py
work/p2/get_coach_data.py
import sys
sys.path.append('work')
from p1.mymodule import *
from p2.mymodule import *
import p1
import p2
p1.mymodule.demo()
p2.mymodule.demo()
#OUTPUT
p1 -- mymodule
p1 -- mymodule