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
    

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

  • 相关阅读:
    JavaScript模态对话框类
    事件模块的演变(1)
    html5中可通过document.head获取head元素
    How to search for just a specific file type in Visual Studio code?
    What do 'lazy' and 'greedy' mean in the context of regular expressions?
    正则非获取匹配 Lookahead and Lookbehind ZeroLength Assertions
    regex length 正则长度问题
    Inversion of Control vs Dependency Injection
    How to return View with QueryString in ASP.NET MVC 2?
    今天才发现Google Reader
  • 原文地址:https://www.cnblogs.com/ChiRou/p/14217835.html
Copyright © 2011-2022 走看看