Python super()使用注意事项,Python super函数
我们能看到的使用super的最常见,也几乎是唯一的形式是:
类别子类(BaseClass):
定义方法(自身):
超级(子类,自身)。方法()
#在这里做些事情.其中,最常见的方法()是__init__()
我以前做过Java,但我对Python的继承是新手。这确实感觉有点奇怪,有时我会感到困惑。当然这是因为Java是单继承,只能通过接口以类似多继承的方式实现,而Python直接支持多继承。
第一次看到这个super()的时候,我就想说,这是什么?为什么Python的super看起来那么奇怪?
super不就是指向父类的实例吗?为什么一定要有两个参数?
而且第一个参数是自己的类名,不是父类的类名!
既然是自己的类名,又何必再写一遍,干脆省略。
为什么第二个参数是self?既然是自我,就不能省略吗?
还有,super()回归是什么鬼?为什么会这样。方法()?他是否返回了基类的实例?
今天就来回答这一系列问题。
1)不就是1)super直接指向父类的实例吗?
首先,它不能被指向,因为子类实例中没有父类实例,这和java不同。详细看这里。
其次,即使和我们想象的一样,子类实例中有一个名为super的指针,指向父类的实例(这个父类实例是在子类实例生成时自动生成的,是子类实例的‘成员’)。
但是由于多重继承的存在,还是会有问题。这也和java不同,java不支持多重继承,Java通过接口实现多重继承。
例如:
当只有单一继承时,一切都是美好的,就像java一样:
你只需要在重写方法的时候用super调用父类的方法,然后做好自己的事情。
但是在多重继承的情况下,一切都不美好:
当艺术家展示他的能力时,他说,父亲,先展示你的能力,然后我就来!
但是谁是父亲呢?他有两个父亲!你不能写两次超级。现身吧,可以吗?
然后我们很自然的认为不可能给super取一个参数,指出super是哪个父类。
比如超级(歌手)。展示自己(),超级(演员)。展现自己()仿佛一切都可以再美好:
不管这种写法有多难看,重复了那么多毫无意义的雷同的台词,但就是行不通。
让我们看看如果一个artist实例调用了。显示能力():
我是人类,我会走路!
我是歌手,我会唱歌!
我是人类,我会走路!
我是演员,我会演戏!
我是艺人,可以代言广告!有必要跟大家说两遍你是人吗?如果这个艺人也是主持人,那他岂不是要大声宣布三次自己是人类?
这显然不好。
而且,这只是第一个。假设你能容忍几次说自己是人,还有一种情况,更糟糕。
例如,artist类没有重写show yourself()方法。用artist实例调用show yourself()会怎么样?
被覆盖的方法自动调用父类,但是有两个父类!哪个叫?叫任意一个(比如从左到右)?
那就没有体现出他另一个家长阶层的特点!比如给歌手打电话,只能说明这个艺人既是歌手也是人,根本不是演员!
两个都打?如果其中一个父类没有这个方法怎么办?还有哪个先叫,哪个后叫?按左右顺序?
总之很乱,编译器说压力很大。
所以,python的super()有两个参数。
先写到这里:
超级(子类,自身)。method()的意思是根据self找到子类的‘父亲’,然后调用这个‘父亲’的方法()
最重要的一点来了:对于一个类来说,谁是它的“父类”取决于它是谁的观点。
之所以引用‘父亲’,是因为‘父亲’不一定是上下级的继承关系,很可能只是兄弟。比如上图,歌手的‘父亲’是‘演员’,但实际上他们是兄弟。
所以以后把这个引用的‘爸爸’换成‘下一节课’。
总之,从不同的实例来看,看到的‘下一个阶层’是不一样的。
这就是super()的第二个参数————self的意义。
如果被歌手实例调用,那么self=歌手实例,super()会从歌手的角度寻找歌手类的‘下一个类’,会找到人类;
如果是由artist实例调用,那么self=artist实例,super()会从artist的角度寻找singer类的‘下一个类’,它会找到actor。
代码如下:
类人(对象):
def show_my_power(自我):
我是一个人,我会走路!)
班级歌手(人):
def show_my_power(自我):
超级(歌手,自己)。show_my_power()
打印(u 我是歌手,我会唱歌!)
类演员(人):
def show_my_power(自我):
超级(演员,自己)。show_my_power()
print(u u我是演员,我会演戏!)
类别艺人(歌手、演员):
及格
if __name__==__main__ :
a=艺术家()
A.show_my_power()运行结果:
我是人,我会走路!
我是演员,我会演戏!
我是歌手,我会唱歌!这里需要注意的是:当一个类从多个类继承时,是按照从左到右的顺序。
也就是说,从艺人的角度来说,首先艺人类的‘下一类’是歌手类,然后歌手类的‘下一类’是演员类。
这是因为歌手在左边写了:艺术家(歌手,演员)
看一下上面代码的执行过程:
因为super()大部分时间用在开头提到的情况,也就是在类的定义语句块里面写:super(这个类名,self)。
所以python3做了一个简化。如果在类定义的语句块中写一个不带参数的super(),就相当于写super(这个类名,self)。
因为super()不仅可以在类的定义中使用,所以这种便利只在类定义体中有效。
涉及
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。