Python super()使用注意事项,Python super函数

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: