yyz notes yyz notes
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

益章

可乐鸡翅
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • python基础

    • python概述

    • python环境搭建

    • python基础语法

    • python关键字与标识符

    • python流程控制

    • python函数

    • python内置函数

    • python面向对象

      • 面向对象、面向过程
      • 面向对象中的属性
      • 面向对象中的方法
      • 封装(三大特性)
      • 继承(三大特性)
      • 多态(三大特性)
      • 反射
      • python中的下划线
      • python中的super()
        • python中的super()
      • python魔法方法
    • python模块与包

    • python文件IO与OS

    • python异常处理机制

  • python高级

  • python模块

  • python设计模式

  • python数据结构与算法

  • django

  • django-DRF

  • flask

  • 自己设计开源pip包

  • 自己设计开源项目

  • python小示例

  • python面试题

  • python
  • python基础
  • python面向对象
YiZhang-You
2023-05-10
目录

python中的super()

# python中的super()

python 中子类会继承父类所有的类属性和类方法。严格来说,类的构造方法其实就是实例方法,因此毫无疑问,父类的构造方法,子类同样会继承。

但我们知道,Python 是一门支持多继承的面向对象编程语言,如果子类继承的多个父类中包含同名的类实例方法,则子类对象在调用该方法时,会优先选择排在最前面的父类中的实例方法。显然,构造方法也是如此。

class People:
    def __init__(self, name):
        self.name = name

    def say(self):
        print("我是人,名字为:", self.name)

class Animal:
    def __init__(self, food):
        self.food = food

    def say(self):
        print("我是动物,名字为:", self.food)

    def display(self):
        print("我是动物,我吃", self.food)

# People中的 name 属性和 say() 会遮蔽 Animal 类中的
class Person(People, Animal):
    pass

per = Person("zhangsan")
per.say()  # 我是人,名字为: zhangsan
# per.display()  # 因为People中没有这个方法,有会先执行People所有会报错,将继承的反过来即可 Animal,People
# Person 类同时继承 People 和 Animal,其中 People 在前。这意味着,在创建 per 对象时,其将会调用从 People 继承来的构造函数。因此我们看到,上面程序在创建 per 对象的同时,还要给 name 属性进行赋值。
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

但如果去掉最后一行的注释,运行此行代码,Python 解释器会报如下错误:

AttributeError: 'Person' object has no attribute 'food'

这是因为,从 Animal 类中继承的 display() 方法中,需要用到 food 属性的值,但由于 People 类的构造方法“遮蔽”了Animal 类的构造方法,使得在创建 per 对象时,Animal 类的构造方法未得到执行,所以程序出错。
1
2
3

在子类中的构造方法中,调用父类构造方法的方式有 2 种,分别是:

  1. 类可以看做一个独立空间,在类的外部调用其中的实例方法,可以向调用普通函数那样,只不过需要额外备注类名(此方式又称为未绑定方法);
  2. 使用 super() 函数。但如果涉及多继承,该函数只能调用第一个直接父类的构造方法。

super() 函数的使用语法格式如下:

python2
	super(Class, obj).__init__(self,...)
python3 
	super().__init__(self,...)
1
2
3
4

在掌握 super() 函数用法的基础上,我们可以尝试修改上面的程序:

class People:
    def __init__(self, name):
        self.name = name

    def say(self):
        print("我是人,名字为:", self.name)

class Animal:
    def __init__(self, food):
        self.food = food

    def say(self):
        print("我是动物,名字为:", self.food)

    def display(self):
        print("我是动物,我吃", self.food)

# People中的 name 属性和 say() 会遮蔽 Animal 类中的
class Person(People, Animal):
    pass

per = Person("zhangsan")
per.say()  # 我是人,名字为: zhangsan

"""
我是人,名字为: zhangsan
"""

# per.display()  # 因为People中没有这个方法,有会先执行People所有会报错,将继承的反过来即可 Animal,People

# Person 类同时继承 People 和 Animal,其中 People 在前。这意味着,在创建 per 对象时,其将会调用从 People 继承来的构造函数。因此我们看到,上面程序在创建 per 对象的同时,还要给 name 属性进行赋值。

# 修改后
class Person2(People, Animal):
    # 自定义构造方法
    def __init__(self, name, food):
        # 调用 People 类的构造方法
        super().__init__(name)
        # super(Person,self).__init__(name) #执行效果和上一行相同
        # People.__init__(self,name)#使用未绑定方法调用 People 类构造方法
        # 调用其它父类的构造方法,需手动给 self 传值
        Animal.__init__(self, food)

per = Person2("zhangsan", "熟食")
per.say()  # 我是人,名字为: zhangsan
per.display()  # 因为People中没有这个方法,有会先执行People所有会报错,将继承的反过来即可 Animal,People
# Person 类同时继承 People 和 Animal,其中 People 在前。这意味着,在创建 per 对象时,其将会调用从 People 继承来的构造函数。因此我们看到,上面程序在创建 per 对象的同时,还要给 name 属性进行赋值。

"""
我是人,名字为: zhangsan
我是动物,我吃 熟食
"""
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

1
编辑 (opens new window)
上次更新: 2023/05/17, 23:08:21
python中的下划线
python魔法方法

← python中的下划线 python魔法方法→

最近更新
01
配置yun源
05-24
02
linux-配置python虚拟环境
05-24
03
linux文件目录管理
05-24
更多文章>
Theme by Vdoing | Copyright © 2023-2023 yizhang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式