zoukankan      html  css  js  c++  java
  • 派生


    派生

    子类中新定义的属性的这个过程叫做派生,子类在使用派生的属性时始终以自己的为准。

    class A1:
        x = 10
    
    
    class B1(A1):
        x = 11  # 派生属性
    
        def f1(self):  # 派生方法
            pass
    
    
    b = B1()
    print(b.x)
    
    11
    

    派生类中使用父类的属性

    • 方式一:self,但这样如果子类中有相同属性,则会优先使用子类的属性,依赖继承关系。
    class A1:
        def f1(self):
            print('AAAA')
    
    class B1(A1):
        def f2(self):
            self.f1()
            
    b = B1()
    b.f2()
    
    AAA
    
    • 方式二:指明道姓使用父类的属性,可以不依赖继承关系。
    class A1:
        def f1(self):
            print('AAAA')
            
    class B1:
        def f2(self):
            A1.f1(self)  # 通过类调用方法,此时为普通函数,需要向self传参。
            
    b = B1()
    b.f2()
    
    AAAA
    
    • 方式三:使用内置函数super(),严格依赖继承关系。

    super([type[, object-or-type]])

    返回一个代理对象,该对象会参照发起属性查找的那个类的mro列表,去super当前所在类的父类中查找属性。即便并没有直接继承关系,super仍然会按照MRO列表继续往后查找。super不会从对象的名称空间和对象所属的父类内查找属性,而是直接从MRO列表的下一个类中查找。

    在Python2中super的使用需要完整地写成super(自己的类名,self) ,而在python3中可以简写为super()。

    class A1:
        def f1(self):
            print('AAAA')
    
    
    class B1(A1):
        def f2(self):
            # 通过对象调用绑定方法会将对象传给self。
            super().f1()
    
    b = B1()
    b.f2()
    

    使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表

    class A:
        def test(self):  # 对象obj和类C均没有test方法则会在父类中查找
            print('from A')  
            super().test()  # super会参照发起属性查找的类的mro列表,去super当前所在类的父类中查找属性。即便A和B并没有继承关系。
            
    class B:
        def test(self):
            print('from B')
            
    class C(A, B):
        pass
    
    print(C.mro())
    obj = C()
    obj.test()
    

    super会参照发起属性查找的类的mro列表,去super当前所在类的父类中查找属性。即便A和B并没有继承关系,也会去B中查找。

    [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
    from A
    from B
    

    更推荐使用super()来重用父类的方法,但不要同时使用两种方法。


    类的特殊属性

    #python为类内置的特殊属性
    类名.__name__ # 类的名字(字符串)
    类名.__doc__ # 类的文档字符串
    类名.__base__ # 类的第一个父类
    类名.__bases__ # 类所有父类构成的元组,仅查看直接父类。
    类名.__dict__ # 类的属性字典
    类名.__module__ # 类定义所在的模块
    类名.__class__ # 实例对应的类(仅新式类中)
    

    取值顺序

    单继承:当前对象的名称空间 --> 子类名称空间 --> 父类 --> 父类的父类... --> object

    class A1:
        def f1(self):
            print('A1.f1')
    
        def f2(self):
            print('A1.f2')
            self.f1()
    
    
    class B1(A1):
        def f1(self):
            print('B1.f1')
    
    b = B1()
    b.f2()
    

    对象b会先在自身名称空间内查找,然后是子类,然后在父类内找到后即会执行f2(),第一行打印 ‘ A1.f2 ’ ,第二行又调用self.f1(),此时self为对象b,同样会先遵循取值顺序,对象 -》子类 -》父类 -》object。

    A1.f2
    B1.f1
    

    多继承会有个取值问题,也就是当多个父类有相同属性的时候,会从哪里取值,这就是后面要说的菱形问题。

  • 相关阅读:
    经典论文翻译导读之《Finding a needle in Haystack: Facebook’s photo storage》
    Etcd源码解析(转)
    etcd集群故障处理(转)
    etcd集群部署与遇到的坑(转)
    LeetCode All in One 题目讲解汇总(转...)
    pyinstaller-python->exe
    3个方法解决百度网盘限速(转)
    Tensorflow 教程系列 | 莫烦Python
    分布式存储Seaweedfs源码分析
    解决Java Web项目中Word、Excel等二进制文件编译后无法打开的问题
  • 原文地址:https://www.cnblogs.com/ChiRou/p/14217835.html
Copyright © 2011-2022 走看看