栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python深入理解super

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1034862.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号