• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    浅谈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 子类 (基类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__】中,知道这个新民成就可以了直接找到这个隐藏的变量,这是个黑魔法慎用

    总结

    属性查找顺序:实例的【__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的方法,方法被覆盖了?

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

    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()的作用相当于

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

    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'
    

    上例代码

    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'}
    

    那如何正确实例化?

    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类的单继承内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • 详细总结Python类的多继承知识
    • python类的继承链实例分析
    • python子类如何继承父类的实例变量
    • Python类成员继承重写的实现
    • Python类继承和多态原理解析
    • Python 继承,重写,super()调用父类方法操作示例
    • python3中类的继承以及self和super的区别详解
    • Python3.5面向对象程序设计之类的继承和多态详解
    • Python面向对象程序设计类的封装与继承用法示例
    • Python基础知识学习之类的继承
    上一篇:PyCharm 安装与使用配置教程(windows,mac通用)
    下一篇:用python开发一款操作MySQL的小工具
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

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