Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python——调用超类';方法?_Python_Oop_Class - Fatal编程技术网

Python——调用超类';方法?

Python——调用超类';方法?,python,oop,class,Python,Oop,Class,我一直在使用: SuperClass.__init__(self, *args, **kwargs) 我的理由是,这明确显示了使用哪个超类,特别是在多重继承的情况下 然而,我遇到的其他代码使用 super(MyClass, self).__init__(*args, **kwargs) 相反 在以下情况下使用时,可能会变得模棱两可: class MyClass(SuperClass1, SuperClass2): def __init__(self, *args, **kwargs)

我一直在使用:

SuperClass.__init__(self, *args, **kwargs)
我的理由是,这明确显示了使用哪个超类,特别是在多重继承的情况下

然而,我遇到的其他代码使用

super(MyClass, self).__init__(*args, **kwargs)
相反

在以下情况下使用时,可能会变得模棱两可:

class MyClass(SuperClass1, SuperClass2):
    def __init__(self, *args, **kwargs):
        super(MyClass, self).__init__(*args, **kwargs) #which SuperClass is being used?

我想知道为什么这种电话形式被广泛采用?有什么好处吗?

对于继承自
对象的新样式类,将使用
super

该类型的
\uuuumro\uuuuuuu
(方法分辨率顺序)属性列出了
super
使用的方法分辨率搜索顺序

>>> class X(object):
    pass

>>> class Y(object):
    pass

>>> class Z(X, Y):
    pass

>>> Z.__mro__
(<class '__main__.Z'>, <class '__main__.X'>, <class '__main__.Y'>, <type 'object'>)

首先,将检查
First
,查看它是否有
\uuuu init\uuuu
,因为
First
在MRO中位于第一位。由于在本例中“First”没有
\uuuu init\uuu
,因此调用
Second
。如果在
First
中有
\uuuuu init\uuuu
,则只会调用该函数

对于现代(新样式)类来说,
super
更受欢迎的原因是它允许协作多重继承。这里有一个例子

>>> class Foo(object):
...     def display(self):
...         print "In Foo"
... 
>>> class Foo2(Foo):
...     def display(self):
...         print "In Foo2"
...         super(Foo2, self).display()
...         print "Back in Foo2"
... 
>>> class Bar(Foo):
...     def display(self):
...         print "In Bar"
...         super(Bar, self).display()
...         print "Back in Bar"
... 
>>> class FooBar(Foo2, Bar):
...     pass
... 
>>> FooBar().display()
In Foo2
In Bar
In Foo
Back in Bar
Back in Foo2
>>> class BarFoo(Bar, Foo2):
...     pass
... 
>>> BarFoo().display()
In Bar
In Foo2
In Foo
Back in Foo2
Back in Bar
注意,我没有做任何事情来更改超类上的
display
方法,但是通过更改超类的排列顺序,我在子类上得到了不同的
display
方法
BarFoo
FooBar
有不同的方法。这是因为它们具有不同的方法解析顺序

巴福__ (, , ) >>>福巴__ (, , )

这意味着
super
将为调用它的每个子类解析为不同的类。这允许每个重写方法改变一小部分正在发生的事情,并且只要其他超类愿意很好地发挥作用,它们仍然可以为方法调用做出贡献。

除了已经发布的好答案之外,这里还有一些附加信息:

  • 旧式类(不是从object派生的类)具有深度优先的方法解析顺序。旧式类以您习惯的方式调用它们的超级类

  • 新样式类(确实从object派生的类)具有更复杂的方法解析顺序。在最高层次上,它类似于广度优先,但比广度优先更复杂。请看下面的精彩解释。使用“super()”允许新样式类遵循此方法解析顺序

  • 如果您使用的是新样式的类,那么仍然可以使用调用超类的旧样式,并且代码仍然可以工作。只有在更复杂的多重继承模式中,差异才会变得明显

>>> class Foo(object):
...     def display(self):
...         print "In Foo"
... 
>>> class Foo2(Foo):
...     def display(self):
...         print "In Foo2"
...         super(Foo2, self).display()
...         print "Back in Foo2"
... 
>>> class Bar(Foo):
...     def display(self):
...         print "In Bar"
...         super(Bar, self).display()
...         print "Back in Bar"
... 
>>> class FooBar(Foo2, Bar):
...     pass
... 
>>> FooBar().display()
In Foo2
In Bar
In Foo
Back in Bar
Back in Foo2
>>> class BarFoo(Bar, Foo2):
...     pass
... 
>>> BarFoo().display()
In Bar
In Foo2
In Foo
Back in Foo2
Back in Bar
>>> BarFoo.__mro__
(<class '__main__.BarFoo'>, <class '__main__.Bar'>, <class '__main__.Foo2'>, <class '__main__.Foo'>, <type 'object'>)
>>> FooBar.__mro__
(<class '__main__.FooBar'>, <class '__main__.Foo2'>, <class '__main__.Bar'>, <class '__main__.Foo'>, <type 'object'>)