python深入理解super

先抄一下官方的文档:官网文档链接

class super([type[, object-or-type]])
返回一个代理对象,它会将方法调用委托给 type 的父类或兄弟类。 这对于访问已在类中被重载的继承方法很有用。

object-or-type 确定用于搜索的 method resolution order。 搜索会从 type 之后的类开始。

举例来说,如果 object-or-type 的 mro 为 D -> B -> C -> A -> object 并且 type 的值为 B,则 super() 将会搜索 C -> A -> object。

object-or-type 的 mro 属性列出了 getattr()super() 所共同使用的方法解析搜索顺序。 该属性是动态的,可以在任何继承层级结构发生更新的时候被改变。

如果省略第二个参数,则返回的超类对象是未绑定的。 如果第二个参数为一个对象,则 isinstance(obj, type) 必须为真值。 如果第二个参数为一个类型,则 issubclass(type2, type) 必须为真值(这适用于类方法)。

super 有两个典型用例。 在具有单继承的类层级结构中,super 可用来引用父类而不必显式地指定它们的名称,从而令代码更易维护。 这种用法与其他编程语言中 super 的用法非常相似。

第二个用例是在动态执行环境中支持协作多重继承。 此用例为 Python 所独有而不存在于静态编码语言或仅支持单继承的语言当中。 这使用实现“菱形图”成为可能,即有多个基类实现相同的方法。 好的设计强制要求这样的方法在每个情况下都具有相同的调用签名(因为调用顺序是在运行时确定的,也因为这个顺序要适应类层级结构的更改,还因为这个顺序可能包括在运行时之前未知的兄弟类)。

对于以上两个用例,典型的超类调用看起来是这样的:

class C(B):
    def method(self, arg):
        super().method(arg)    # This does the same thing as:
                               # super(C, self).method(arg)

除了方法查找之外,super() 也可用于属性查找。 一个可能的应用场合是在上级或同级类中调用 描述器。

请注意 super() 是作为显式加点属性查找的绑定过程的一部分来实现的,例如 super().getitem(name)。 它做到这一点是通过实现自己的 getattribute() 方法,这样就能以可预测的顺序搜索类,并且支持协作多重继承。 对应地,super() 在像 super()[name] 这样使用语句或操作符进行隐式查找时则未被定义。

还要注意的是,除了零个参数的形式以外,super() 并不限于在方法内部使用。 两个参数的形式明确指定参数并进行相应的引用。 零个参数的形式仅适用于类定义内部,因为编译器需要填入必要的细节以正确地检索到被定义的类,还需要让普通方法访问当前实例。

———————————————————————————————————————————————————————
写一下我的场景和问题:
我有一个基类,有四个子类继承基类,有一个孙类继承四个子类,原先只有基类有属性,子类只有方法无子类属性,现在给某几个子类增加了属性
我的需求是:孙类能继承基类、指定子类的属性和方法
直接上代码吧:

class A:
    def __init__(self):
        print('Enter A init')
        self.a = 2
        self.b = 'aaa'

    def aa(self, m):
        print('self is {0} @A.add'.format(self))
        self.a += m


class C(A):
    def __init__(self):
        print('Enter C init')
        super().__init__()
        self.b = 'ccc'
    def cc(self, m):
        print(self.a)

class B(A):
    def __init__(self):
        print('Enter B init')
        super().__init__()
        self.b = 'bbb'
    def bb(self, m):
        print('self is {0} @B.add'.format(self))
        print(self.a)

class D(A):
    def dd(self, m):
        print(self.a)

————————————————————————————————————————————————————————————————————————————————
class E(D,C,B):
    def __init__(self):
        super().__init__()
        print('**********')
    def ee(self, m):
        print(self.a)
        print(self.b)

    ee = E()  #实例化时,MRO为D→C→B→A
    print(ee.b)  #D无属性,则找C ,找到了
	运行结果:
		Enter C init
		Enter B init
		Enter A init
		**********
		ccc
————————————————————————————————————————————————————————————————————————————————
	#修改为:
	class E(D,C,B):
	    def __init__(self):
	        super(D, self).__init__()
	        print('**********')
	    def ee(self, m):
	        print(self.a)
	        print(self.b)
    ee = E()  #实例化时,MRO为C→B→A
    print(ee.b)  #D无属性,则找C ,找到了	

运行结果:
		Enter C init
		Enter B init
		Enter A init
		**********
		ccc 
     
————————————————————————————————————————————————————————————————————————————————
	#修改为:
	class E(D,C,B):
	    def __init__(self):
	        super(C, self).__init__()
	        print('**********')
	    def ee(self, m):
	        print(self.a)
	        print(self.b)
    ee = E()  #实例化时,MRO为B→A
    print(ee.b)  #B的b属性为bbb
	
运行结果:
	Enter B init
	Enter A init
	**********
	bbb
————————————————————————————————————————————————————————————————————————————————
	#修改为:
	class E(D,C,B):
	    def __init__(self):
	        super(B, self).__init__()
	        print('**********')
	    def ee(self, m):
	        print(self.a)
	        print(self.b)
    ee = E()  #实例化时,MRO为A
    print(ee.b)  #A的b属性为aaa
	
运行结果:
Enter A init
**********
aaa

从上面代码可以直观的看出对孙类实例化时执行的过程,就可以控制孙类继承的属性

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值