首页 AI Studio教育版 帖子详情
Python 学习笔记 —— 05
收藏
快速回复
AI Studio教育版 文章课程答疑 611 2
Python 学习笔记 —— 05
收藏
快速回复
AI Studio教育版 文章课程答疑 611 2

复制粘贴csdn的,csdn被给我发,难受。

 

> 前言:第五节课主要加深扩展类的相关知识,重点在继承。虽然多次入门python,但是对继承几乎没用过,所以这次学到很多新只是。也明白到,在Python中,开发时,继承是一个很重要的功能——常常在别人的代码上改东西,而不是从头自己写。


@[TOC](目录)
———————————————
# 《百度飞桨领航团零基础Python速成营》 课程笔记 —— 05


## 一、类的继承
> [菜鸟教程 - Python 子类继承父类构造函数说明](https://www.runoob.com/w3cnote/python-extends-init.html)
> https://www.runoob.com/w3cnote/python-extends-init.html


- 目前从代码上看,可以得出类的继承,就相当于把父类的东西全都**复制粘贴**到子类里去了。
- 然后,如果子类有和父类命名冲突的就会**重写覆盖**。
```python
# 父类
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)
```


### 1)子类 的 构造函数
> 定义:
class 子类名(父类名):
情况1,如果子类有新增的属性,那么需要在子类__init方法中,调用父类的__init__
情况2,如果子类没有新增的属性,子类不需要写__init__方法
使用:
对象名 = 子类名(参数)
继承的好处:代码重用,升级功能(重写),新增功能(新的方法)


- 菜鸟教程下的一篇笔记总结的很好,
```python
情况一:子类需要自动调用父类的方法:子类不重写__init__()方法,实例化子类后,会自动调用父类的__init__()的方法。
(即,子类不需要再往构造函数里加东西,所以不用重写)


情况二:子类不需要自动调用父类的方法:子类重写__init__()方法,实例化子类后,将不会自动调用父类的__init__()的方法。
(即,子类需要加东西,要重写,正常情况即使重写也要保留父类的,所以大多会是第三种情况)


情况三:子类重写__init__()方法又需要调用父类的方法:使用super关键词:
super(子类,self).__init__(参数1,参数2,....)
class Son(Father):
  def __init__(self, name):   
    super(Son, self).__init__(name)


(不用super也可以,老师上课讲了种较好理解的,这样也可以)
class Son(Athlete):
    def __init__(self,name,name2):
        Father.__init__(self,name)
```


### 2)子类 的 方法重写
> 子类方法与父类方法完全相同,子类若重写了父类的方法,则子类对象调用方法时就是调用的自己类中重新的方法。


 - 其实子类构造函数应该也算一种重写(只是重写完后还能调用父类的执行?)。
 - 值得注意的是!!!!不止是方法的名字要一样,连参数也要一致。不然仍会被认定为2个不同的方法。大概父类构造函数就是因为这样才没有被重写覆盖。


### 3)专业名词:多态性


> 多态性:一个事物多种形态
> 多态的好处是:减少重复代码,分离经常改变的代码与不经常改变的代码,使得代码可维护性提高。


- 从代码上看,多态性其实就相当于把类作为参数传入函数内,在函数内被调用。(应该也算高阶函数的一种)
- 当2个类方法名一样,功能不一样时,就可以使用多态性来减少重复性,使代码更加整洁。
```python
loren = get_coach_data('mywork/loren.txt')
mark = get_coach_data('mywork/mark.txt')


loren = Rugby(loren.pop(0),loren.pop(0),loren.pop(0),loren)
mark = OtherAthlete(mark.pop(0),mark.pop(0),mark.pop(0),mark)


def print_rugby(athlete):


    print(athlete.name)
    print(athlete.dob)
    print(athlete.squat)
    print(athlete.top3())


print_rugby(loren)
print_rugby(mark)
```
### 4)多继承
- 用起来和单继承区别不大,唯一需要注意的就是:多个父类有相同的属性或方法名,这种情况应该避免。


> [菜鸟教程 - Python super() 函数](https://www.runoob.com/python/python-func-super.html)
> https://www.runoob.com/python/python-func-super.html


```python
#多个父类有相同的属性或方法名,这种情况应该避免
class Father(): 
    def __init__(self):
        self.color = 'black'


    def talk(self):
        print("---爸爸的表达能力---")


class Mather():
    def __init__(self):
        self.color = 'white' # 重复命名了。
    def talk(self):
        print("--妈妈也能表达")
    def smart(self):
        print("---妈妈聪明的头脑---")


class Child(Father,Mather):
    pass


child1 = Child()
child1.talk()
child1.smart()
print(child1.color)
# 这里会输出Father类的color。应该涉及到继承优先级的问题。
```
## 二、提问
### 1)问题①
> 导入athlete模块,使用athlete模块下的所有代码


- 其实就是教:“`函数→类→模块→包`”的封装思路。
```python
import sys
sys.path.append('mywork')


# import athlete
# print(dir(athlete))
from athlete import *


loren = get_coach_data('mywork/loren.txt')
mark = get_coach_data('mywork/mark.txt')


loren = Rugby(loren.pop(0),loren.pop(0),loren.pop(0),loren)
mark = OtherAthlete(mark.pop(0),mark.pop(0),mark.pop(0),mark)


def print_rugby(athlete):


    print(athlete.name)
    print(athlete.dob)
    print(athlete.squat)
    print(athlete.top3())


print_rugby(loren)
print_rugby(mark)fj飞桨
```


### 2)问题②
> 如果有一个模块mymodule.py中也包含get_coach_data函数,该怎么区分这两个函数呢


```python
import sys
sys.path.append('work')


from p1.mymodule import *
from p2.mymodule import *
import p1
import p2
p1.mymodule.demo()
p2.mymodule.demo()
# 输出:
# p1 -- mymodule
# p1 -- mymodule
```

0
收藏
回复
全部评论(2)
时间顺序
AIStudio810261
#2 回复于2021-02

python有些特性其实是为了尽量扩展灵活性而做出来的, 但你要是真正用了这些特性, 代码维护上就很痛苦了. 尽量中规中矩

0
回复
AIStudio810258
#3 回复于2021-02

收获满满啊,加油,共同进步!

0
回复
在@后输入用户全名并按空格结束,可艾特全站任一用户