当前位置:   article > 正文

python进阶

python进阶

在这里插入代码片# python进阶

一.模块和包的使用

1.自己写的每个python文件都可与是模块或者包:
  • smart.py:

    num = 10
    def my_sum(a,b):
        return a + b
    def my_sub(a,b):
        return a - b
    
    • 1
    • 2
    • 3
    • 4
    • 5
2.模块的使用:
  • """
    方式1:导入整个模块,然后通过`模块名.要使用的内容`进行使用
        import 模块名
        
    import smart
    print(smart.num)
    print(smart.my_sum(2, 3))
    
    方式2【推荐】:从模块中导入指定要使用的内容,然后进行使用【推荐】
        from 模块名 import 要使用的内容
    
    from smart import my_sub
    print(my_sub(5, 2))
    
    方式3【不推荐】:导入模块中的所有内容,然后进行使用
        from 模块名 import *
        
    from smart import *
    print(my_sum(1, 1))
        
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
3.模块起别名:(名字太长或者名字有冲突)
  • """
    情况1:给模块起别名
        import 模块名 as 别名
        
    情况2:给模块中导入的内容起别名
        from 模块名 import 内容 as 别名
    
    注意:一旦起了别名之后,那么只能通过别名使用相应的内容
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
4.模块内置变量:
(1)模块内置变量__name__.py
"""
模块内置变量:__name__

在 Python 中的每个模块都有一个 __name__ 内置变量,该内置变量的值在以下2种情况时不同:

比如现在有 1 个模块:smart.py

1)若是直接运行 smart.py 的代码,在其中获取 smart 模块的 __name__,它的值是:'__main__'
2)若是另一个模块引入了 smart 模块,并且在另一个模块中获取 smart 模块的 __name__,它的值是:'smart'
"""
---------------------------------------------------
"""
__name__ 的作用:

这个特性可以用于判断一个模块是被直接运行还是被导入,并根据不同的情况执行不同的代码。

例如,一个模块中有一些测试代码,希望只在直接运行该模块时执行这些测试代码,而在被其他模块导入时不执行。可以使用如下方式:

if __name__ == '__main__':
    # 模块功能测试代码
    
注意:这样做的目的是,其他模块导入该模块时,被导入模块中的测试代码不会被执行
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
(2)模块内置变量__all__.py
"""
模块内置变量:__all__

使用 `from 模块 import *` 的方式导入模块的内容时,默认只会导入被导入模块中 __all__ 内置
变量中指定的内容
"""

"""
注意:
1)在 smart.py 模块的最上方添加右边的代码:__all__ = ['num', 'sum']
2)在添加之前或添加之后,分别运行当前文件的代码查看效果

结果:
1)smart.py 中未添加 __all__ = ['num', 'sum'] 内容之前,`from smart import *` 默认
会导入 smart 模块的所有内容
2)smart.py 中添加了 __all__ = ['num', 'sum'] 内容之后,`from smart import *` 只能
导入 __all__ 中限定的内容
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
(3)模块搜索路径:
"""
当你导入一个模块,Python解析器对模块位置的搜索顺序是:
1)当前目录
2)如果不在当前目录,Python则搜索系统路径

注意:模块搜索路径列表存储在 sys 模块的sys.path变量中。
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
5.包:
# python内置的包和模块:内置->本身就有,可以直接进行使用
# import random
# import os
# import multiprocessing
# import threading
# import re
# 内置的包和模块是在 python 解释器安装目录的 Lib 下面


# python第三方的包和模块:第三方->本身没有,使用的时候需要先下载安装

# 安装命令:pip install 包名或模块名 -i 下载镜像源地址
# 卸载命令:pip uninstall 包名或模块名

# 阿里云 https://mirrors.aliyun.com/pypi/simple/
# 豆瓣(douban) https://pypi.douban.com/simple/
# 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
# 中国科学技术大学 https://pypi.mirrors.ustc.edu.cn/simple/

# pandas:数据分析处理开源库
# 安装第三方的包和模块是在 python 解释器安装目录的 Lib/site-packages 下面
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

二.面向对象编程(解释)

1.思想:

1.对象就是存放数据和功能的容器,用对象去写程序,就是面向对象的思想。

2.类:

1.类也是容器,是用来存放同类对象共用的数据和功能的。

2.类包含两个组成部分:

  • 属性:比如姓名,年龄,身高,肤色等
  • 方法:比如吃饭,睡觉,飞行,歌唱等

3.对象:

1.对象是类的实例,是具体的实体。

三.类和实例

1.类的定义:

"""   
注意:类名的命名规则按照大驼峰命名法,即名字中的各个单词首字母都大写

类中方法定义语法:
class 类名(object):
    def 方法名1(self): 
        ...
        
    def 方法名2(self): 
        ...        
注意:类中方法的格式和函数类似,也可以设置参数和返回值,但是需要设置第一个参数为self
"""

#类的定义
class Hero(object):
    hero_work = '射手'
    count = 0

    def __init__(self, name, speed, hp, atk):
        self.name = name
        self.speed = speed
        self.hp = hp
        self.atk = atk
        self.equipment = []
        Hero.count += 1

    def get_hero_info(self):
        print(f'英雄属性:名字:{self.name} 移速:{self.speed}'
              f' 生命值:{self.hp} 攻击力:{self.atk}')

    def set_hero_speed(self, speed_plus):
        self.speed += speed_plus

    def buy_equipment(self, e_name):
        self.equipment.append(e_name)
        
    def __str__(self)return f'英雄属性:名字:{self.name} 移速:{self.speed}'
               f' 生命值:{self.hp} 攻击力:{self.atk}'
        	   f' 装备:{self.equipment}'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

2.实例化

"""
Python中,可以根据已经定义的类去创建对象。

注意:类创建对象的过程叫类的`实例化`,所有对象有时也被称为`实例对象`。

格式:
    对象变量名 = 类名()
    
通过对象调用方法:
    对象变量名.方法名()
"""

# 实例化(要对初始化函数的形参进行传值)
hero1_obj = Hero('鲁班七号', 450, 3000, 100)
hero2_obj = Hero('后裔', 460, 3100, 110)
hero3_obj = Hero('虞姬', 470, 3200, 120)

#通过调用方法输出全部属性
print(hero1_obj.get_hero_info())

#对象调用方法(进行对属性的更改和增加)
hero1_obj.set_hero_speed(10)
hero1_obj.buy_equipment('反甲')

#每次实例化一个对象,都会调用初始化函数一次,count+1
print(hero1_obj.count)

#类中有__str__函数,用来输出对象的全部属性,所以可以直接输出对象,否则输出的是对象在内存中的地址
print(hero1_obj)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

3.实例属性和类属性

"""
实例属性:属于单个实例对象的属性,不同实例对象互相独立,互不相干。

添加/修改:
    1)方法内:self.属性名 = 值
    2)类外部:实例对象.属性名 = 值
访问:
    1)方法内:self.实例属性名
    2)类外部:实例对象.属性名
注意:实例属性只能通过实例对象进行访问
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
"""
类属性:属于类的属性,只有一份,被这个类的所有实例对象所共有,记录一类事物共同需要保存的内容。

添加:
    1)在类定义内部,但在类方法外面的变量就是类属性
访问:
    1)类名.类属性名【推荐】
    2)实例对象.类属性名【不推荐】
修改:
    1)类名.类属性名 = 值
    
注意:类属性只能通过 `类名.类属性名=值` 的方式修改
"""

class Hero:
    #类属性
    hero_work = '射手'
    count = 0

    def __init__(self, name, speed, hp, atk):
        self.name = name
        self.speed = speed
        self.hp = hp
        self.atk = atk
        self.equipment = []
        Hero.count += 1

hero1_obj = Hero('鲁班七号', 450, 3000, 100)
print(Hero.count)
print(hero1_obj.count)

"""
类属性有什么用?记录一类事物共同需要保存的内容
需求:记录一共创建了多少只狗的实例对象?
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

4.self 和 绑定方法:

"""
在 Python 类中规定,实例方法的第一个参数是实例对象本身,并且约定俗成,把其名字写为self。

某个对象调用其某个方法时,Python 解释器会自动把这个对象作为第一个参数传递给对应方法

通俗理解:通过哪个对象调用方法,方法中 self 就是这个对象
"""
"""
在方法中使用 self,可以获取到调用当前方法的对象,进而获取到该对象的属性和方法

self作用:用来区分不同对象的属性和方法,谁调用方法就是谁的属性和方法
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
# 在Python中,绑定方法是指将一个函数绑定到一个对象上,使其成为该对象的一个方法。绑定方法可以通过以下两种方式实现:

# 1.使用类定义方法:在类定义中,将函数定义为类的方法,即将函数作为类的属性,并在调用时将实例对象作为第一个参数传入。
class MyClass:
    def my_method(self, arg1, arg2):
        # 方法体
        pass

# 创建实例对象
obj = MyClass()
# 调用绑定方法
obj.my_method(arg1, arg2)

# 2.使用types.MethodType函数:将函数绑定到对象上,使其成为对象的一个方法。
import types

class MyClass:
    pass

# 定义函数
def my_method(self, arg1, arg2):
    # 方法体
    pass

# 创建实例对象
obj = MyClass()
# 绑定方法
obj.my_method = types.MethodType(my_method, obj)
# 调用绑定方法
obj.my_method(arg1, arg2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
#所以当类本身调用函数方法时, self必须传参数

class Animal(object):
    """动物类"""
    def __init__(self):
        print('Animal类中的__init__方法')
        self.type = '动物'

    def show_info(self):
        print(f'Animal类中的show_info方法,类型:{self.type}')

class Dog(Animal):
    def __init__(self):
        print('Dog类中的__init__方法')
        self.type = '狗'

    def show_info(self):
        print(f'Dog类中的show_info方法,类型:{self.type}')

        # 需求:如果在子类的方法中能够调用到父类中的同名 show_info 方法
        # self必须写,因为当类去调用函数方法时,就成了普通函数,就不是绑定方法了,需要传self
        Animal.show_info(self)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

5.魔法方法:

  • 类的 __init__ 方法:
    1)__init__ 方法叫做 对象的初始化方法,在 创建一个对象后会被自动调用,不需要手动调用
    2)__init__ 方法的作用:给创建的对象添加属性
    
    • 1
    • 2
    • 3
  • 类的 __str__ 方法:
    1)如果直接 print 打印对象,会看到创建出来的对象在内存中的地址
    2)当使用 print(对象变量名) 输出对象的时候,只要类中定义了 __str__ 方法,就会打印 __str__ 方法返回值
    
    __str__ 方法作用:
    1)主要返回对象属性信息,print(对象变量名) 输出对象时直接输出 __str__ 方法返回的描述信息
    2)注意:__str__ 方法的返回值必须是 字符串类型
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

6.实例方法,类方法,静态方法

"""
实例方法:属于实例对象的方法,第一个形参是self,只能通过实例对象进行调用,self形参就是实例对象
"""

class Dog(object):
    """狗类"""
    def __init__(self, _name, _age):
        self.name = _name
        self.age = _age

    # 实例方法:只能通过实例对象进行调用
    def show_info(self):
        print(f'我的名字:{self.name}, 年龄:{self.age}')

# 创建一个 Dog 对象
dog1 = Dog('小黄', 1)
dog1.show_info()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
"""
类方法:属于类对象(类)的方法,可以通过类名或实例对象名进行调用

作用:用于对一类事物进行操作,和具体的某个实例对象没有直接关联关系,若类中的方法方法在逻辑上采用
类本身来调用更合理,那么这个方法就可以定义为类方法
需求:在类中提供一个方法,展示一共有多少只狗

定义:
    class 类名(object):
        @classmethod
        def 类方法名(cls):
            pass

注意:类方法必须有一个形参,一般叫 cls,调用类方法是 cls 形参不用传递,python解释器会自动传递
"""

class Dog(object):
    # 类属性
    count = 0

    def __init__(self, _name, _age):
        # 实例属性
        self.name = _name
        self.age = _age

        # 只要__init__调用,就说明创建了一个对象,类属性 count 就加1
        Dog.count += 1

    # 实例方法:只能通过实例对象进行调用
    def show_info(self):
        print(f'我的名字:{self.name}, 年龄:{self.age}')

    # 需求:提供一个显示一共有多少只狗的方法
    @classmethod
    def show_dog_count(cls):
        print(f'现在一共有{cls.count}只狗')

Dog.show_dog_count()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
"""
静态方法:主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,
不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个
类中,便于使用和维护。

定义:
    class 类名(object):
        @staticmethod
        def 静态方法名():
            pass

注意:静态方法不需要有 self 或 cls 参数
"""

class SysManager(object):
    """管理系统类"""
    # 需求:提供一个显示菜单的方法
    @staticmethodpy
    def show_menu():
        print('菜单')

SysManager.show_menu()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

7.小练习

"""
面向对象编程的步骤:
1)分解对象:分解出编程任务中涉及到哪些对象
    拆解很细:地瓜、烧烤炉、人、火、碳
    咱们这个案例很简单,只拆解一个:地瓜对象

2)抽象成类:将分解出的对象抽象成类,分析类中有哪些属性和方法
    地瓜类(SweetPotato)
        属性:这个类的对象有哪些数据需要保存(不要凭空想象,结合需求进行分析)
            state:地瓜的状态
            cooked_time:地瓜的烧烤总时间
            condiments:添加的佐料

        方法:这个类的对象能够干什么、做什么(不要凭空想象,结合需求进行分析)
            __init__(self):地瓜对象的初始化方法,给创建的每个地瓜对象添加初始的属性:state、cooked_time
            cook(self, time):地瓜烧烤的方法,有一个形参 time,接收地瓜每次烧烤的时间
            __str__(self):返回一个字符串,包含地瓜对象的状态和烧烤的总时间
            add_condiment(self, item):添加烧烤佐料方法,有一个形参item,接收添加的佐料

3)定义出类
4)创建对象,通过对象调用方法或使用属性完成编程任务
"""


class SweetPotato(object):
    """地瓜类"""

    def __init__(self):
        """地瓜对象的初始化方法,给创建的每个地瓜对象添加初始的属性:state、cooked_time"""
        self.state = '生的'
        self.cooked_time = 0
        self.condiments = []  # 保存地瓜对象烧烤过程中,添加过的佐料

    def __str__(self):
        """返回一个字符串,包含地瓜对象的状态、烧烤总时间"""
        return f'地瓜状态:{self.state},烧烤总时间:{self.cooked_time},添加过的佐料:{self.condiments}'

    def cook(self, time):
        """
        功能:对地瓜进行烧烤
        参数:
        * time:接收一个数字,代表每一次烧烤烤几分钟
        """
        # ① 将当前地瓜对象烧烤的总时间进行累加,再加time
        # sp1.cooked_time += time
        self.cooked_time += time

        # ② 判断当前地瓜对象的烧烤总时间,进行地瓜状态的改变
        if 0 <= self.cooked_time < 3:
            # sp1.state = '生的'
            self.state = '生的'
        elif 3 <= self.cooked_time < 6:
            self.state = '半生不熟'
        elif 6 <= self.cooked_time < 8:
            self.state = '熟了'
        else:
            self.state = '烤糊了'

    def add_condiment(self, item):
        """
        功能:添加佐料
        参数:
        * item:接收添加的佐料
        """
        # 保存佐料
        self.condiments.append(item)


# 创建一个地瓜对象
sp1 = SweetPotato()
print(sp1)

# 烤一次地瓜
sp1.cook(2)
sp1.add_condiment('糖')
print(sp1)

# 烤一次地瓜
sp1.cook(2)
sp1.add_condiment('辣椒面')
print(sp1)

# 烤一次地瓜
sp1.cook(2)
sp1.add_condiment('番茄酱')
print(sp1)

# 烤一次地瓜
sp1.cook(2)
sp1.add_condiment('玛莎拉')
print(sp1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91

四.面向对象三大特性(封装,继承,多态)

1.封装(隐藏属性)

1.含义:
  • 1.定义类的过程,也是封装

  • 2.对属性和方法增加访问权限控制:公开和私有(当前面加_ _ 在类里面调用可以,类外面不可以)

  • 私有属性:self._ _name = name

  • 私有方法:def _ _sleep(self):

2.封装例子:
class Dog(object):
    """狗类"""
    def __init__(self, _name, _age):
        self.name = _name
        self.__age = _age

    def get_age(self):
        """提供给外部获取私有属性方法"""
        return self.__age

    def set_age(self,_age):
        """提供给外部设置私有属性的方法"""
        if _age <= 0:
            print('年龄必须大于0')
            return
        self.__age = _age

dog1 = Dog('小黑',5)
#公开属性可以直接调用
print(dog1.name)

#--对变量进行了隐藏,类外不能调用私有属性
# print(dog1.age)   
#需要调函数接口让别人使用,类的设计者保护了数据不被别人修改(类内的函数可以调用私有属性)
print(dog1.get_age())

#私有属性的本质就是改了属性的名字 改为: _类名__属性名
#所以通过改后的名字还是可以访问到,python没有真正的私有
print(dog1._Dog__age)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

2.继承

1.单继承和多继承
"""
单继承:子类定义时只继承一个父类
"""

class Animal(object):
    """动物类"""
    def eat(self):
        print('吃东西')

# Dog 类定义时只继承了 Animal 类
class Dog(Animal):
    """狗类"""
    pass

# 创建一个 Dog 对象
dog1 = Dog()
dog1.eat()
#-------------------------------------------------------------------
"""
多继承:子类定义时同时继承多个父类
"""

class SmallDog(object):
    def eat(self):
        print('小口吃东西')

    def sleep(self):
        print('小憩一会')

class BigDog(object):
    def drink(self):
        print('大口喝水')

    def sleep(self):
        print('呼呼大睡')

# SuperDog 类定义时同时继承了 SmallDog 和 BigDog
class SuperDog(SmallDog, BigDog):
    pass

# 创建一个 SuperDog 对象
sd1 = SuperDog()
# SuperDog 从 SmallDog 继承了 eat 方法
sd1.eat()
# SuperDog 从 BigDog 继承了 drink 方法
sd1.drink()

"""
子类继承的多个父类中有多个同名方法,默认调用先继承的那个父类中的同名方法。
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
2.多层继承
"""
多层继承:继承关系为多层传递,如生活中的爷爷、父亲、儿子
"""

# 爷爷类
class Animal(object):
    """动物类"""
    def eat(self):
        print('吃东西')

# 爸爸类
class Dog(Animal):
    """狗类"""
    def drink(self):
        print('喝水')

# 儿子类
class SuperDog(Dog):
    pass

# 创建一个 SuperDog 对象
sd1 = SuperDog()
sd1.drink()
sd1.eat()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
3.重写
1.重写的目的:

从父类继承的方法不能满足子类的需要,为了拓展功能而重写

2.重写方式:
"""
重写形式:
1)在子类中定义了一个和父类(包括爷爷类及以上)同名的方法(参数也一样),即为对父类(包括爷爷类
及以上)的方法重写

注意:重写之后子类调用同名方法,默认只会调用子类的
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 完全重写

    class Animal(object):
        """动物类"""
        def __init__(self):
            print('Animal类中的__init__方法')
            self.type = '动物'
    
        def show_info(self):
            print(f'Animal类中的show_info方法,类型:{self.type}')
    
    class Dog(Animal):
    
        def __init__(self):
            """
            对父类继承的__init__方法进行重写
            """
            print('Dog类中的__init__方法')
            self.type = '狗'
    
        def show_info(self):
            """
            对父类继承的show_info方法进行重写
            """
            print(f'Dog类中的show_info方法,类型:{self.type}')
    
    # 创建一个 Dog 对象
    dog1 = Dog()
    dog1.show_info()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    class PayClass(object):
    
        def pay(self):
            pass
    
        def refund(self):
            pass
    
    
    class AliPay(PayClass):
        def pay(self):
            print('支付宝付款')
    
        def refund(self):
            print('支付宝退款')
    
    class WeChat(PayClass):
        def pay(self):
            print('微信支付')
    
        def refund(self):
            print('微信退款')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 增强重写(在父类基础上重写):

    子类重写了父类的方法之后,若在子类方法中还想调用父类的同名方法

    """
    子类重写了父类的方法之后,若在子类方法中还想调用父类的同名方法。
    可以使用如下方式:
    1)父类名.同名方法(self, 形参1, ……)
    2)super(子类名, self).同名方法(形参1, ……)
    3)super().同名方法(形参1, ……):是方法 2 的简写,推荐的写法
    """
    
    class Animal(object):
        """动物类"""
        def __init__(self):
            print('Animal类中的__init__方法')
            self.type = '动物'
    
        def show_info(self):
            print(f'Animal类中的show_info方法,类型:{self.type}')
    
    class Dog(Animal):
        def __init__(self):
            print('Dog类中的__init__方法')
            self.type = '狗'
    
        def show_info(self):
            print(f'Dog类中的show_info方法,类型:{self.type}')
    
            # 需求:如果在子类的方法中能够调用到父类中的同名 show_info 方法
            #方法1;父类名.同名方法(self,...)    
            # self必须写,因为当类去调用函数方法时,就成了普通函数,就不是绑定方法了,需要传self
            Animal.show_info(self)
            #方式2:super(子类名,self).同名方法
            super(Dog,self).show_info()
            #方式3:super().同名方法   方式2的简写
            super().show_info()
    
    # 创建一个 Dog 对象
    dog1 = Dog()
    dog1.show_info()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
3.super父类方法调用(父类方法被重写后,又想调用):

#根据__mro__链表的顺序,(自下而上,自左向右)

  • 单继承 ( C = > B = > A)

    
    class A(object):
        def func(self):
            print('A类中的func函数')
    
    class B(A):
        def func(self):
            super().func()
            print('B类中的func函数')
    
    class C(B):
        def func(self):
            super().func()
            print('C类中的func函数')
    
    # 创建一个C这个类的对象
    obj = C()
    # 思考:代码的执行结果是什么???
    obj.func()
    
    # A类中的func函数
    # B类中的func函数
    # C类中的func函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 多继承 (D = > B = > C = > A)

    class A(object):
        def func(self):
            print('A类中的func函数')
    
    class C(A):
        def func(self):
            super().func()
            print('C类中的func函数')
    
    class B(A):
        def func(self):
            super().func()
            print('B类中的func函数')
    
    class D(B, C):
        def func(self):
            super().func()
            print('D类中的func函数')
    
    # 创建一个 D 这个类的对象
    obj = D()
    # 思考:代码执行的结果是什么???
    obj.func()
    
    # A类中的func函数
    # C类中的func函数
    # B类中的func函数
    # D类中的func函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
3.私有和继承
"""
私有和继承:
    父类中的私有属性和方法不能被子类继承
    
如果子类想访问到父类中的私有属性和方法怎么办?

答:在父类中提供一个公有方法,在父类的公有方法中进行访问私有属性和方法,以此来达到子类能够间接
访问到父类中的私有属性和方法的效果。
"""

class Animal(object):
    """动物类"""
    def __init__(self, _name, _age):
        self.name = _name
        self.__age = _age

    def __pee(self):
        """pee:撒尿"""
        print('上厕所嘘嘘')

    def show_info(self):
        print(f'名字:{self.name},年龄:{self.__age}')

    def sleep(self):
        # 睡觉撒尿
        self.__pee()
        print('睡觉了
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/261665
推荐阅读
相关标签