iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python中的super()面向对象编程
  • 376
分享到

Python中的super()面向对象编程

2024-04-02 19:04:59 376人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录python super()面向对象编程一、为什么要用 super()二、什么是 super三、继承中使用 super1、实例方法使用 super2、构造方法使用 super四、

Python super()面向对象编程

一、为什么要用 super()

当子类重写了父类方法时,又想调用父类的同名方法时,就需要用到 super()

二、什么是 super

  • 在 Python 中,super 是一个特殊的类
  • super() 就是使用 super 类创建出来的对象
  • 实际应用的场景:子类在重写父类方法时,调用父类方法

三、继承中使用 super

1、实例方法使用 super

类图

实际代码


class A:
    def __init__(self):
        self.n = 1

    def add(self, m):
        print(f'AAA [self] is {id(self)}')
        print(f'AAA [self.n] is {self.n}')
        self.n += m


class B(A):
    def __init__(self):
        self.n = 100

    # 重写父类方法
    def add(self, m):
        # 子类特有代码
        print(f'BBB [self] is {id(self)}')
        print(f'BBB [self.n] is {self.n}')

        # 调用父类方法
        super().add(m)

        self.n += m


b = B()
b.add(2)
print(b.n)

 

# 输出结果
BBB [self] is 4489158560
BBB [self.n] is 100

AAA [self] is 4489158560
AAA [self.n] is 100

104

super().add()  的确调用了父类方法
重点:此时父类方法的 self 并不是父类实例对象,而是子类实例对象

2、构造方法使用 super


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

    def prints(self):
        print("Animale name is ", self.name)


class Dog(Animal):
    def __init__(self, name, age):
        # 调用父类的 init 构造方法
        super(Dog, self).__init__(name)
        self.age = age

    def prints(self):
        # 调用父类的方法
        super(Dog, self).prints()
        print("Dog age is ", self.age)


dog = Dog("小汪", 10)
dog.prints()

 

# 输出结果
Animale name is  小汪
Dog age is  10

这里用了 super(子类名, self) ,和上面的 super() 是一样效果

调用父类方法有两种方式

  • super().父类方法() 
  • super(子类名, self).父类方法() 

其实还有第三种

在 Python  2.x 的时候,如果需要调用父类的方法,还可以用

父类名.方法(self)

  • 这种方式,Python 3.x 还是支持的
  • 过不不推荐,因为父类名发生变化的话,方法调用位置的类名也要同步修改

通过父类名调用父类方法(不推荐)


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

    def prints(self):
        print("Animale name is ", self.name)


class Dog(Animal):
    def __init__(self, name, age):
        # 调用父类的 init 构造方法
        Animal.__init__(self, name)
        self.age = age

    def prints(self):
        # 调用父类的方法
        Animal.prints(self)
        print("Dog age is ", self.age)


dog = Dog("小汪", 10)
dog.prints()


# 输出结果
Animale name is  小汪
Dog age is  10

通过父类名调用的这种方式,是需要传 self 参数的哦

温馨提示:
开发时, 父类名.方法() super().方法() 两种方式不要混用哈

灵魂拷问一:既然已经重写了子类的构造方法,为什么还要去调用 super?
子类需要重写父类方法来实现子类独有的功能,但同时又需要依赖父类方法来完成某些逻辑

实际栗子

  • 在实现多线程的时候(后面会详细展开说多线程
  • 父类 Thread 的构造方法包含了很多逻辑代码
  • 子线程虽然需要实现子类独有功能,但仍需父类方法来处理其他逻辑


from threading import Thread


class MyThread(Thread):
    def __init__(self, name):
        # 1、实现子类独有功能
        print("子类线程 %s" % name)
        # 2、需要依赖父类方法完成其他功能
        super().__init__(name=name)

四、多继承中使用 super

类图

实际代码


# 多继承
class Animal:
    def __init__(self, animalName):
        print(animalName, 'is an animal.')


# Mammal 继承 Animal
class Mammal(Animal):
    def __init__(self, mammalName):
        print(mammalName, 'is a mammal.')
        super().__init__(mammalName)


# CannotFly 继承 Mammal
class CannotFly(Mammal):
    def __init__(self, mammalThatCantFly):
        print(mammalThatCantFly, "cannot fly.")
        super().__init__(mammalThatCantFly)


# CannotSwim 继承 Mammal
class CannotSwim(Mammal):
    def __init__(self, mammalThatCantSwim):
        print(mammalThatCantSwim, "cannot swim.")
        super().__init__(mammalThatCantSwim)


# Cat 继承 CannotSwim 和 CannotFly
class Cat(CannotSwim, CannotFly):
    def __init__(self):
        print('I am a cat.');
        super().__init__('Cat')


# Driver code
cat = Cat()
print('')
bat = CannotSwim('Bat')

 

# 输出结果
I am a cat.
Cat cannot swim.
Cat cannot fly.
Cat is a mammal.
Cat is an animal.

Bat cannot swim.
Bat is a mammal.
Bat is an animal.

好像挺奇怪的,从输出结果看,为什么 CannotSwim 类里面的 super().__init__() 调用的是 CannotFly 类里面的方法呢?不是应该调用 CannotSwim 的父类 Mamal 的方法吗?

灵魂拷问二:super 的执行顺序到底是什么?

  • 其实 super() 并不一定调用父类的方法
  • super() 是根据类的 MRO 方法搜索顺序来决定调用谁的
  • super() 真正调用的是 MRO 中的下一个类,而不一定是父类
  • 当然,这种情况只会出现在多继承

先来看看 Cat 的 MRO


print(Cat.__mro__)

(<class '__main__.Cat'>, <class '__main__.CannotSwim'>, <class '__main__.CannotFly'>, <class '__main__.Mammal'>, <class '__main__.Animal'>, <class 'object'>)

从 Cat 的 MRO 可以看到

  • CannotSwim 后面跟的是 CannotFly 而不是 Mamal
  • 所以 CannotSwim 类里面的 super() 会调用 CannotFly 里面的方法

多继承的栗子二

实际代码


class A:
    def __init__(self):
        self.n = 2

    def add(self, m):
        # 第四步
        # 来自 D.add 中的 super
        # self == d, self.n == d.n == 5
        print('self is {0} @AAA.add'.fORMat(self))
        self.n += m
        # d.n == 7


class C(A):
    def __init__(self):
        self.n = 4

    def add(self, m):
        # 第三步
        # 来自 B.add 中的 super
        # self == d, self.n == d.n == 5
        print('self is {0} @CCC.add'.format(self))
        # 等价于 suepr(C, self).add(m)
        # self 的 MRO 是 [D, B, C, A, object]
        # 从 C 之后的 [A, object] 中查找 add 方法
        super().add(m)

        # 第五步
        # d.n = 7
        self.n += 4
        # d.n = 11


class B(A):
    def __init__(self):
        self.n = 3

    def add(self, m):
        # 第二步
        # 来自 D.add 中的 super
        # self == d, self.n == d.n == 5
        print('self is {0} @BBB.add'.format(self))
        # self 的 MRO 是 [D, B, C, A, object]
        # 从 B 之后的 [C, A, object] 中查找 add 方法
        # 从 C 找 add 方法
        super().add(m)

        # 第六步
        # d.n = 11
        self.n += 3
        # d.n = 14


class D(B, C):
    def __init__(self):
        self.n = 5

    def add(self, m):
        # 第一步
        print('self is {0} @DDD.add'.format(self))
        # self 的 MRO 是 [D, B, C, A, object]
        # 从 D 之后的 [B, C, A, object] 中查找 add 方法
        # 从 B 找 add 方法
        super().add(m)

        # 第七步
        # d.n = 14
        self.n += 5
        # self.n = 19


d = D()
d.add(2)
print(d.n)
 

先看看 D 类的 MRO


print(D.__mro__)

(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

输出结果


self is <__main__.D object at 0x10c14a190> @DDD.add
self is <__main__.D object at 0x10c14a190> @BBB.add
self is <__main__.D object at 0x10c14a190> @CCC.add
self is <__main__.D object at 0x10c14a190> @AAA.add
19

调用顺序的确是 D、B、C、A

执行顺序


class D(B, C):          class B(A):            class C(A):             class A:
def add(self, m):       def add(self, m):      def add(self, m):       def add(self, m):
super().add(m)  1.--->  super().add(m) 2.--->  super().add(m)  3.--->  self.n += m
 self.n += 5   <------6. self.n += 3    <----5. self.n += 4     <----4. <--|
(14+5=19)               (11+3=14)              (7+4=11)                (5+2=7)
 

执行顺序图


到此这篇关于Python super()面向对象编程的文章就介绍到这了,更多相关Python super()内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Python中的super()面向对象编程

本文链接: https://www.lsjlt.com/news/134701.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python中的super()面向对象编程
    目录Python super()面向对象编程一、为什么要用 super()二、什么是 super三、继承中使用 super1、实例方法使用 super2、构造方法使用 super四、...
    99+
    2024-04-02
  • python 面向对象编程
    文章目录 前言如何理解面向对象编程在 python 中如何使用面向对象编程定义类创建对象self添加和获取对象属性添加属性类外添加属性类中添加属性 访问属性类外访问属性类中访问属性 ...
    99+
    2023-08-31
    python 开发语言
  • Python-面向对象编程
    面向对象最重要的概念就是类(Class)和实例(Instance),类是抽象的模板,比如人类、动物类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。 以人类为例,创建一个实例为 xiaomi...
    99+
    2023-01-31
    面向对象 Python
  • Python面向对象编程
      面向对象最重要的概念就是类(Class)和实例(Instance),Java比较熟了,下面贴代码注释   class Student(object): def __init__(self, name, score): ...
    99+
    2023-01-30
    面向对象 Python
  • Python OOP 面向对象编程
    参考:黑马程序员教程 - Python基础 面向对象 OOP三大特性,且三个特性是有顺序的: 封装 继承 多态 封装 指的就是把现实世界的事务,封装、抽象成编程里的对象,包括各种属性和方法。这个一般都很简单,不需要多讲。 唯一要注意的...
    99+
    2023-01-31
    面向对象 Python OOP
  • Python面向对象编程(一)
    目录一、程序中定义类和对象1、 定义类2、 定义对象二、定制对象独有特征1、引入2、定制对象独有特征3、对象属性查找顺序4、类定义阶段定制属性三、对象的绑定方法1、类使用对象的绑定对...
    99+
    2024-04-02
  • Python面向对象编程(三)
    目录一、isinstance和issubclass二、反射(hasattr和getattr和setattr和delattr)1、反射在类中的使用2、反射在模块中的使用3、实例:基于反...
    99+
    2024-04-02
  • Python面向对象编程(二)
    目录一、对象的继承1、类的构造函数继承__init__():2、继承关系中,对象查找属性的顺序二、类的派生1、派生方法一(类调用)2、派生方法二(super)三、类的组合四、多父类继...
    99+
    2024-04-02
  • Python面向对象编程 一
    一、类    面向对象是对函数进行分类和封装,其主要目的是提高程序的重复实用性,让开发更方便快捷。    在我们的认知中,我们会根据属性相近的东西归为一类。例如:鱼类,鱼类的共同属性是呼吸,卵生。任何一个鱼都在此鱼类基础上创建的。    定...
    99+
    2023-01-31
    面向对象 Python
  • 5 Python的面向对象编程
    概述         在上一节,我们介绍了Python的函数,包括:函数的定义、函数的调用、参数的传递、lambda函数等内容。在本节中,我们将介绍Python的面向对象编程。面向对象编程(Object-Oriented Programmi...
    99+
    2023-08-31
    python 面向对象 继承 运算符重载
  • python 面向对象编程(2)
    文章目录 前言封装多态类属性和实例属性定义以及访问类属性修改类属性实例属性 类方法静态方法 前言 前面我们介绍了 python 类和对象以及继承、私有权限,那么今天我们将来介绍 py...
    99+
    2023-08-31
    python 开发语言
  • python面向对象编程小结
    这个是跟着教程一步一步走过来的,所以记下自己学习的过程。 一、类基础 1、类的定义 class <类名>:     <其他语句> class <类名>(父类名):     <其他语句> >...
    99+
    2023-01-31
    小结 面向对象 python
  • Python 面向对象编程详解
    Python 面向对象 方法没有重载# 在其他语言中,可以定义多个重名的方法,只要保证方法签名唯一即可。方法签名包含3个部分:方法名、参数数量、参数类型。 Python 中,方法的的...
    99+
    2022-12-30
    python面向对象程序设计 python面向对象的三个基本特征 python面向对象编程简单例子
  • Python面向对象高级编程
      1、__slots__ Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性 class Student(object): __slots__ = ('name',...
    99+
    2023-01-30
    面向对象 高级编程 Python
  • Python面向对象编程基础
    面向对象编程是Python中的核心之一,面向对象的核心并不是概念,语法,使用有多么复杂,而是一种编程思想,并不是掌握了类创建与使用就真正掌握了面向对象编程,这需要在不断工作与练习中逐步提升;抛去代码,我们先来看现实世界的基本概念: 类: 我...
    99+
    2023-01-31
    面向对象 基础 Python
  • JAVA面向对象中如何继承super
    小编今天带大家了解JAVA面向对象中如何继承super,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习“JAVA面向对象中如何继承sup...
    99+
    2023-06-28
  • 【python】面向对象编程之@prop
      @property装饰器作用:把一个方法变成属性调用 使用@property可以实现将类方法转换为只读属性,同时可以自定义setter、getter、deleter方法   @property&@.setter class ...
    99+
    2023-01-31
    面向对象 python prop
  • PHP面向对象编程:面向接口编程
    dip 是一种设计模式,通过创建依赖于接口而非具体实现的类来实现松耦合和易维护。好处包括灵活性、可测试性和可扩展性。要实现 dip,请定义接口、创建实现接口的类,并将接口作为依赖项传递给...
    99+
    2024-05-10
    php 面向对象 php面向对象编程
  • Python GUI 编程:面向对象的方法
    ...
    99+
    2024-04-02
  • 怎么理解Python中的面向对象编程
    本篇内容主要讲解“怎么理解Python中的面向对象编程”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么理解Python中的面向对象编程”吧!Python支持多种类型的编程范式,例如过程式编程、...
    99+
    2023-06-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作