python中的super方法,Python super()使用注意事项

  python中的super方法,Python super()使用注意事项

  在Python中,可以通过调用父类名直接调用父类方法。在多重继承中,使用Super()是一个好习惯。下面这篇文章主要介绍Python中super用法的相关信息,通过示例代码非常详细的介绍。有需要的朋友可以参考一下。

  

目录
Python super用法附:super典型用法总结

  

Python Super用法

  本文先来介绍一下super。我相信大部分人都是这样使用super的;

  #就是我有一个类,比如男,然后继承另一个类,比如人。然后我用super()。__init__()在这个Male的init函数中调用其父类的初始函数,这个Male是它的子类。

  从对象打印导入操作

  类别人员:

  def __init__(self,name):

  self.name=name

  班级男(人):

  def __init__(self,name):

  超级()。__init__(名称)

  self.gender=男性

  m=男性(“小阳”)

  op(m)

  #输出:

  男性0x23669a19fa0。性别=男性。name=xiaoyang

  当我们经常使用super的时候,我们通常认为super是一个方法或者函数,但实际上super是一个严肃的类,是一个内置名称。那么super()不调用函数,而是super()建立一个超级对象。

  类型(超级)

  类别“类型”

  虽然我们通常使用super()括号,里面什么都没有,但是完整版的super应该有两个参数。第一个参数是类型,即类,第二个参数是类型或对象。例如,第二个参数确定这个函数绑定到那个对象或类,第二个参数确定使用哪个mro,而第一个参数确定从mro链中的哪个类开始

  从对象打印导入操作

  类别人员:

  def __init__(self,name):

  self.name=name

  班级男(人):

  def __init__(self,name):

  #超级()。__init__(名称)

  超级(男,自我)。__init__(名称)

  self.gender=男性

  m=男性(“小阳”)

  op(m)

  #输出:

  公0x171f680afa0。性别=男性。name=xiaoyang

  #其实我们来看看刚超()。__init__(名字),相当于super(男,自己)。__init__(名称)。

  然后这个超级(男,自己)就做了这样的事。首先它得从自我这个对象得到mro,然后他会找到第一个论证,就是男性在mro中的位置。那么在目前的情况下,男性是第一位的(男性人身对象)。接下来,他将开始寻找Male之后的类,它找到的第一个是Person。然后它会看有没有函数__init__本人,然后它会找到这个函数。然后它把这个__init__绑定到self,在这里可以理解为这个人的__init__函数传入的这个self就是super中的这个self,也就是说Person的这行代码。__init__(self,name)相当于super(男,self)的这行代码。_ _ init _(名称)。

  为什么不用人呢?__init?

  __(self,name)是有几个原因:

  

  • 在未来有可能会改变基类的名字,甚至会改变继承的方式,在这种情况下如果使用 super 的话就什么都不用管,应为他会自动追随这个 mro 找到正确的 class ,但是用这种命名的 class 的话就要全部修改,这样更容易引起错误
  • 其实 super 是动态的,他会根据 self 的 mro 进行寻找,而 self 也就是传进来的这个 argument 它本身是动态的,也就是说同样一个函数里面,我用 super 在不改变这个函数的情况下我有可能会拿到不同的 class。

  在来看这个示例:

  

from objprint import op

  class Animal:

   def __init__(self, age):

   self.age = age

  class Person(Animal):

   def __init__(self, age, name):

   super().__init__(age)

   self.name = name

  class Male(Person):

   def __init__(self,age, name):

   # super(Male, self).__init__(age, name)

   super(Person, self).__init__(age, name)

   self.gender = "male"

  m = Male(18, xiaoyang)

  op(m)

  如果在 Male 中正常的使用它super(Male, self).__init__(age, name),那么它就会正常的初始化所有的东西,它会访问这个 Person 的__init__,然后 Person 的__init__会访问 Animal 的__init__,最后就完成了这个 Male。

  那如果把它改成super(Person, self).__init__(age, name),那么就会报错,因为当我们使用super(Person, self)的时候,self 的 mro 链是 Male Person Animal 然后是 object,那第一个参数它由于是 Person,所以他会从 Person 后面的那个 class 也就是 Animal 开始找,那 Animal 是有__init__函数的,但是 Animal 的__init__只有一个参数 age,所以当我们传入 age name 的时候那就错了,这时候就只需要将它改成只传进去一个 age 如:super(Person, self).__init__(age)就可以了,同时也跳过了 Person。

  

总结 super 的两个参数也就是第一个 type 和第二个 type 或者 object 分别决定了什么:

  第一个只决定了在 mro 这个链上从哪里开始找

  第二个是决定使用这个函数的对象和 mro

  

  super 并不是只能在 class 里面使用的,它可以在任何一个地方使用,我只要给定 第二个参数 object 或者 class ,在给定第一个参数从哪里开始找,我就能使用它的函数,例如:

  

# 那这里的话就是从 m 这个 object 的 mro 上寻找 Male 后面开始的 __init__ 函数,这样实际上就找到了 Person 的 __init__ 函数,然后再用 Person 的 __init__ 函数对 m 这个 object 做初始化

  from objprint import op

  class Animal:

   def __init__(self, age):

   self.age = age

  class Person(Animal):

   def __init__(self, age, name):

   super().__init__(age)

   self.name = name

  class Male(Person):

   def __init__(self,age, name):

   super(Person, self).__init__(age)

   self.gender = "male"

  m = Male(18, xiaoyang)

  op(m)

  print("----------------------")

  super(Male, m).__init__(20, "xiaoyang")

  op(m)

  # 输出:

  <Male 0x18412d13f70

   .age = 18,

   .gender = male

  >

  ----------------------

  <Male 0x18412d13f70

   .age = 20,

   .gender = male,

   .name = xiaoyang

  >

  

  

附:super的典型用法

  很多人对super直观的理解是,调用父类中的方法:

  

class A:

      def test(self):

          print(A.test)

  class B(A):

      def test(self):

          super().test()

          print(B.test)

  b = B()

  b.test()

  
执行结果为:

  

A.test
B.test

  

  从上面的例子看来,super确实可以调用父类中的方法。但是看下面的代码:

  

class A:

      def test(self):

          print(A.test)

  class TestMixin:

      def test(self):

          print(TestMixin.test)

          super().test()

  class B(TestMixin, A):

      def test(self):

          print(B.test)

          super().test()

  b = B()

  b.test()

  打印结果:

  

B.test
TestMixin.test
A.test

  

  上面的代码先创建B的对象b,然后调用b.test(),但是B的test函数通过super(),会调到第一个父类TestMixin的test函数,因为TestMixin是B的第一个父类。

  TestMixin中的test函数中通过super调到了A中的test函数,但是A不是TestMixin的父类。在这个继承体系中,A和TestMixin都是B的父类,但是A和TestMixin没有任何继承关系。为什么TestMixin中的super会调到A中的test函数呢?

  

  

总结

  到此这篇关于Python中Super用法的文章就介绍到这了,更多相关PythonSuper详解内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

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