返回顶部
首页 > 资讯 > 后端开发 > Python >浅谈Python类的单继承相关知识
  • 559
分享到

浅谈Python类的单继承相关知识

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

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

摘要

目录一、类的继承二、继承的定义、查看继承的特殊属性和方法三、继承中的访问控制四、方法的重写、覆盖override五、继承中的初始化上文我们总结过了python多继承的相关知识,没看过

上文我们总结过了python多继承的相关知识,没看过的小伙伴们也可以去看看,今天给大家介绍Python类的单继承相关知识。

一、类的继承

面向对象三要素之一,继承Inheritance

人类和猫类都继承自动物类。

个体继承自父母,继承了父母的一部分特征,但也可以有自己的个性。

在面向对象的世界中,从父类继承,就可以直接拥有父类的属性和方法,这样就可以减少代码、多服用。子类可以定义自己的属性和方法


class Animal:
 
    def __init__(self,name):
        self._name = name
 
    def shout(self):
        print("{}  shouts".fORMat(self.__class__.__name__))
    @property
    def name(self):
        return self._name
 
 
class Cat(Animal):
    pass
 
 
class Dog(Animal):
    pass
 
a = Animal("monster")
a.shout()           #   Animal  shouts
 
 
cat = Cat("garfield")
cat.shout()         #   Cat  shouts
print(cat.name)     #   garfield
 
 
dog = Dog("ahuang")
dog.shout()         #   Dog  shouts
print(dog.name)     #   ahuang

上例中我们可以看出,通过继承、猫类、狗类不用写代码,直接继承了父类的属性和方法

继承:

  • class Cat(Animal)这种形式就是从父类继承,括号中写上继承的类的列表。
  • 继承可以让子类重父类获取特征(属性、方法)

父类:

  • Animal就是Cat的父类,也称为基类、超类

子类:

  • Cat 就是Animal的子类,也成为派生类  

二、继承的定义、查看继承的特殊属性和方法

格式


class 子类 (基类1[,基类2,……]):
    语句块

如果类定义时,没有基类列表,等同于继承自【object】。在python3中,【object】类是所有对象基类

查看继承的特殊属性和方法

特殊属性  含义 示例
__base__  类的基类 
__bases__  类的基类元组 
__mro__  显示方法查找顺序,基类的元组 
mro()  同上  int.mro()
__subclasses__()  类的子类列表  int.__subclasses__()

三、继承中的访问控制


class Animal:
    __COUNT = 100
    HEIGHT = 0
 
    def __init__(self,age,weight,height):
        self.__COUNT += 1
        self.age = age
        self.__weight = weight
        self.HEIGHT = height
 
    def eat(self):
        print("{}  eat".format(self.__class__.__name__))
 
    def __getweight(self):
        print(self.__weight)
 
    @claSSMethod
    def showcount1(cls):
        print(cls.__COUNT)
 
    @classmethod
    def __showcount2(cls):
        print(cls.__COUNT)
 
    def showcount3(self):
        print(self.__COUNT)
 
class Cat(Animal):
    NAME = "CAT"
    __COUNT = 200
 
#a = Cat()              #   TypeError: __init__() missing 3 required positional arguments: 'age', 'weight', and 'height'
a = Cat(30,50,15)
a.eat()                 #   Cat  eat
print(a.HEIGHT)         #   15
#print(a.__COUNT)        #   AttributeError: 'Cat' object has no attribute '__COUNT'
#print(a.__showcount2)   #   AttributeError: 'Cat' object has no attribute '__showcount2'
#print(a.__getweight)    #   AttributeError: 'Cat' object has no attribute '__getweight'
a.showcount3()   #   101
a.showcount1()   #  100
print(a.NAME)    #    CAT
 
print(Animal.__dict__)  #   {'__module__': '__main__', '_Animal__COUNT': 100, 'HEIGHT': 0, '__init__': <function Animal.__init__ at 0x020DC228>, 'eat': <function Animal.eat at 0x020DC468>, '_Animal__getweight': <function Animal.__getweight at 0x02126150>, 'showcount1': <classmethod object at 0x020E1BD0>, '_Animal__showcount2': <classmethod object at 0x020E1890>, 'showcount3': <function Animal.showcount3 at 0x021264F8>, '__dict__': <attribute '__dict__' of 'Animal' objects>, '__weakref__': <attribute '__weakref__' of 'Animal' objects>, '__doc__': None}
print(Cat.__dict__)     #   {'__module__': '__main__', 'NAME': 'CAT', '_Cat__COUNT': 200, '__doc__': None}
print(a.__dict__)       #   {'_Animal__COUNT': 101, 'age': 30, '_Animal__weight': 50, 'HEIGHT': 15}

从父类继承、自己没有的,就可以到父类中找

私有的都是不可访问的,但是本质上依然是改了名称放在这个属性所在的类的了【__dict__】中,知道这个新民成就可以了直接找到这个隐藏的变量,这是个黑魔法慎用

总结

  • 继承时,共有的,子类和实例都可以随意访问;私有成员被隐藏,子类和实例不可直接访问,当私有变量所在类内方法中可以访问这个私有变量
  • Python通过自己一套实现,实现和其他语言一样的面向对象的继承机制

属性查找顺序:实例的【__dict__】------类的【__dict__】-----父类【__dict__】

如果搜索这些地方后没有找到异常,先找到就立即返回

四、方法的重写、覆盖override


class Animal:
 
    def shout(self):
        print("Animal shouts")
 
class Cat(Animal):
 
    def shout(self):
        print("miao")
 
a = Animal()
a.shout()       #   Animal shouts
b  = Cat()
b.shout()       #   miao
 
print(a.__dict__)       #   {}
print(b.__dict__)       #   {}
print(Animal.__dict__)  #   {'__module__': '__main__', 'shout': <function Animal.shout at 0x017BC228>, '__dict__': <attribute '__dict__' of 'Animal' objects>, '__weakref__': <attribute '__weakref__' of 'Animal' objects>, '__doc__': None}

Cat类中shout为什么没有打印Animal中shout的方法,方法被覆盖了?

  • 这是因为,属性查找顺序:实例的【__dict__】------类的【__dict__】-----父类【__dict__】

那子类如何打印父类的同命的方法

  • super()可以访问到父类的属性

class Animal:
 
    def shout(self):
        print("Animal shouts")
 
class Cat(Animal):
 
    def shout(self):
        print("miao")
 
    def shout(self):
        print("super():   " , super())
        print(super(Cat, self))
        super().shout()
        super(Cat,self).shout()   # 等价于super().shout()
        self.__class__.__base__.shout(self)  #不推荐使用
 
a = Animal()
a.shout()       #   Animal shouts
b  = Cat()
b.shout()       #   super():    <super: <class 'Cat'>, <Cat object>>
                #   <super: <class 'Cat'>, <Cat object>>
                #   Animal shouts
                #   Animal shouts
                #   Animal shouts
print(a.__dict__)       #   {}
print(b.__dict__)       #   {}
print(Animal.__dict__)  #   {'__module__': '__main__', 'shout': <function Animal.shout at 0x019AC228>, '__dict__': <attribute '__dict__' of 'Animal' objects>, '__weakref__': <attribute '__weakref__' of 'Animal' objects>, '__doc__': None}
print(Cat.__dict__)     #   {'__module__': '__main__', 'shout': <function Cat.shout at 0x019F6150>, '__doc__': None}
 

super(Cat,self).shout()的作用相当于

  • 调用,当前b的实例中找cat类基类中,shout的方法

那对于类方法和静态方法是否也同样适用尼?


class Animal:
    @classmethod
    def class_method(cls):
        print("class_method")
 
    @staticmethod
    def static_method():
        print("static_methond_animal")
 
class Cat(Animal):
    @classmethod
    def class_method(cls):
        super().class_method()  #   class_method
        print("class_method_cat")
 
    @staticmethod
    def static_method(cls,self):
        super(Cat,self).static_method()
        print("static_method_cat")
 
b = Cat()
b.class_method()    #   class_method
                    #   class_method_cat
b.static_method(Cat,b)
                    #   static_methond_animal
                    #   static_method_cat

这些方法都可以覆盖,原理都一样,属性字典的搜索顺序

五、继承中的初始化

看以下一段代码,有没有问题


class A:
    def __init__(self,a):
        self.a = a
 
class B(A):
    def __init__(self,b,c):
        self.b = b
        self.c = c
 
    def printv(self):
        print(self.b)
        print(self.a)
 
a = B(100,300)
print(a.__dict__)       #   {'b': 100, 'c': 300}
print(a.__class__.__bases__)    #   (<class '__main__.A'>,)
a.printv()      #   100
                #   AttributeError: 'B' object has no attribute 'a'

上例代码

  • 如果B类定义时声明继承自类A,则在B类中__bases__中是可以看到类A
  • 这和是否调用类A的构造方法是两回事
  • 如果B中调用了A的构造方法,就可以拥有父类的属性了,如果理解这一句话?

class A:
    def __init__(self,a):
        self.a = a
 
class B(A):
    def __init__(self,b,c):
        super().__init__(b+c)
        # A.__init__(self,b+c)
        self.b = b
        self.c = c
 
    def printv(self):
        print(self.b)
        print(self.a)
 
a = B(100,300)
print(a.__dict__)       #   {'a': 400, 'b': 100, 'c': 300}
print(a.__class__.__bases__)    #   (<class '__main__.A'>,)
a.printv()      #   100
                #   400

作为好的习惯,如果父类定义了__init__方法,你就改在子类__init__中调用它【建议适用super()方法调用】

那子类什么时候自动调用父类的【__init__】方法?

例子一:【B实例的初始化会自动调用基类A的__init__方法】


class A:
    def __init__(self):
        self.a1 = "a1"
        self.__a2 = "a2"
        print("A init")
 
class B(A):
    pass
 
b = B()     #   A init
print(b.__dict__)   #   {'a1': 'a1', '_A__a2': 'a2'}

例子二:【B实例的初始化__init__方法不会自动调用父类的初始化__init__方法,需要手动调用】


class A:
    def __init__(self):
        self.a1 = "a1"
        self.__a2 = "a2"
        print("A init")
 
class B(A):
    def __init__(self):
        self.b1 = "b1"
        self.__b2 = "b2"
        print("b init")
        #A.__init__(self)
 
b = B()     #   b init
print(b.__dict__)   #   {'b1': 'b1', '_B__b2': 'b2'}

那如何正确实例化?

  • 注意,调用父类的__init__方法,出现在不同的位置,可能导致出现不同的结果

class Animal:
    def __init__(self,age):
        print("Animal init")
        self.age = age
 
    def show(self):
        print(self.age)
 
class Cat(Animal):
    def __init__(self,age,weight):
        #调用父类的__init__方法的顺序 决定show方法的结果
        super(Cat, self).__init__(age)
        print("Cat init")
        self.age = age + 1
        self.weight = weight
 
a = Cat(10,5)
a.show()        #   Animal init
                #   Cat init
                #   11

怎么直接将上例中所有的实例属性改变为私有属性?

  • 解决办法,一个原则,自己的私有属性,就该自己的方法读取和修改,不要借助其他类的方法,即父类或者派生类

class Animal:
    def __init__(self,age):
        print("Animal init")
        self.__age = age
 
    def show(self):
        print(self.__age)
 
class Cat(Animal):
    def __init__(self,age,weight):
        #调用父类的__init__方法的顺序 决定show方法的结果
        super(Cat, self).__init__(age)
        print("Cat init")
        self.__age = age + 1
        self.__weight = weight
 
    def show(self):
        print(self.__age)
 
a = Cat(10,5)
a.show()        #   Animal init
                #   Cat init
                #   11
print(a.__dict__)   #   {'_Animal__age': 10, '_Cat__age': 11, '_Cat__weight': 5}

到此这篇关于浅谈Python类的单继承相关知识的文章就介绍到这了,更多相关Python类的单继承内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 浅谈Python类的单继承相关知识

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

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

猜你喜欢
  • 浅谈Python类的单继承相关知识
    目录一、类的继承二、继承的定义、查看继承的特殊属性和方法三、继承中的访问控制四、方法的重写、覆盖override五、继承中的初始化上文我们总结过了Python多继承的相关知识,没看过...
    99+
    2024-04-02
  • 简单谈谈Python面向对象的相关知识
    一、私有化 上篇说过封装,既将我们不想让别人看到代码的内容,但是又需要用到的内容,通过类内部调用来实现调用。 说到这里却不得不提一下上篇的: class Person(objec...
    99+
    2024-04-02
  • 浅谈Java自定义注解相关知识
    目录一、自定义注解格式二、注解本质分析三、注解属性及类型四、注解属性类型五、注解属性赋值简化操作一、自定义注解格式 分析 Java 中自带的 @Override 注解 , 源码如下 ...
    99+
    2024-04-02
  • 详细总结Python类的多继承知识
    目录一、Python不同版本的类二、多继承三、多继承弊端四、Python多继承实现五、多继承的缺点六、Mixin 七、Mixin类一、Python不同版本的类 P...
    99+
    2024-04-02
  • Python基础知识学习之类的继承
    目录一、继承的格式二、单继承三、多继承四、重写父类方法五、打印继承关系六、调用父类方法七、私有属性与方法一、继承的格式 类的继承格式如下,括号中的为父类名。 class 类名(父...
    99+
    2024-04-02
  • 浅谈C++不同继承之间的关系
    目录公有继承:“是一个” 的关系派生类与基类:继承关系中的构造函数与析构函数继承关系中拷贝构造函数继承关系中赋值运算符的重载通过组合体现 “有一个...
    99+
    2023-05-16
    C++继承关系
  • 浅谈python的函数知识
    目录函数参数的两大分类位置参数可变长参数名称空间总结函数参数的两大分类 形式参数 函数定义阶段括号所写的参数 实际参数 函数调用阶段括号内传入的参数 形参与实参的关系...
    99+
    2024-04-02
  • Python类中的单继承和多继承用法
    本篇内容主要讲解“Python类中的单继承和多继承用法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python类中的单继承和多继承用法”吧!前言Python面向对象编程语言,有List、Str...
    99+
    2023-06-02
  • 浅谈nodejs中的类定义和继承的套路
    javascript是一门极其灵活的语言。 灵活到你无法忍受! 我个人喜欢强类型的语言,例如c/c++,c#等。 但是js代表着未来,所以需要学习。 js中类定义以及继承有n多种方式,现在来学习一下n...
    99+
    2022-06-04
    套路 浅谈 定义
  • Python类的相关知识有哪些
    小编给大家分享一下Python类的相关知识有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、什么是类类(class),作为代码的父亲,可以说它包裹了很多有趣...
    99+
    2023-06-15
  • python--初始面向对象:类的相关知识,对象的相关知识
    引子假设你是一个开发人员,现在需要你开发一款叫做当然很简单,两个角色,1个人物,1个boss,且人物和boss都有不同的技能,比如人物用觉醒技能秒了boss,掉了xx装备,boss用大招秒了人物,人物死亡,怎么描述这种不同的人物和他们的功能...
    99+
    2023-01-30
    相关知识 面向对象 对象
  • 浅谈Python从全局与局部变量到装饰器的相关知识
    全局变量与局部变量 # num1是全局变量 num1 = 1 # num2是局部变量 def func(): num2 = 2 在函数外(且不在函数里)定义的变量是全局变量...
    99+
    2024-04-02
  • python数据类型相关知识扩展
    目录一、命名元祖二、在自动化测试场景中的应用三、三目运算符四、推导式五、字典推导式一、命名元祖 在python基础中, 我们学习元祖的时候,取元祖内部的元素都是通过索引来进行取值的。...
    99+
    2024-04-02
  • 一文深入了解Python中的继承知识点
    目录1 类继承1.1 继承的简单例子2 继承的类型2.1 单继承2.2 多继承2.3 多级继承2.4 分层继承2.5 Python中的混合继承3 总结1 类继承 Python 是面向...
    99+
    2024-04-02
  • Python入门学习之类的相关知识总结
    目录前言一、类的定义和使用二、类的方法三、类的属性四、类中常用特殊方法前言 Python是面向对象的程序设计(Object Oriented Programming)。 面向对象的程...
    99+
    2024-04-02
  • 怎么在Python中实现类的单继承
    怎么在Python中实现类的单继承?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、类的继承面向对象三要素之一,继承Inheritance人类和猫类都继承自动物类。个体继承自父...
    99+
    2023-06-15
  • Python的类、继承和多态简单介绍
    这篇文章主要讲解了“Python的类、继承和多态简单介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python的类、继承和多态简单介绍”吧!类的定义假如要定义一个类 Point,表示二维...
    99+
    2023-06-17
  • Python中类的mro与继承关系详解
    目录前言类继承mro总结前言 版本: windows 10.0python 3.8 类 在Python数字比较与类结构中有简略提到类,那么什么是类呢? 在python中定义一个类很简...
    99+
    2024-04-02
  • 总结Python变量的相关知识
    一、变量的定义 程序中,数据都是临时存储在内存中,为了更快速的查找或使用这个数据,通常我们把这个数据在内存中存储之后,给整个数据定义一个名称,这个名称就是变量。 变量就是在存储数据...
    99+
    2024-04-02
  • 一篇文章带你搞懂Python类的相关知识
    目录一、什么是类二、类的方法三、类的特性四、总结一、什么是类 类(class),作为代码的父亲,可以说它包裹了很多有趣的函数和方法以及变量,下面我们试着简单创建一个吧。 这样就算创...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作