我正在努力了解它的用法super().从它的外观来看,可以创建两个子类,就好了.
我很想知道以下2个孩子班级之间的实际差异.
class Base(object):
def __init__(self):
print "Base created"
class ChildA(Base):
def __init__(self):
Base.__init__(self)
class ChildB(Base):
def __init__(self):
super(ChildB, self).__init__()
ChildA()
ChildB()
Run Code Online (Sandbox Code Playgroud) 我是Python面向对象编程的新手,我很难理解super()函数(新样式类),尤其是涉及多重继承时.
例如,如果你有类似的东西:
class First(object):
def __init__(self):
print "first"
class Second(object):
def __init__(self):
print "second"
class Third(First, Second):
def __init__(self):
super(Third, self).__init__()
print "that's it"
Run Code Online (Sandbox Code Playgroud)
我没有得到的是:Third()该类是否会继承构造函数方法?如果是,那么将使用super()运行哪一个?为什么?
如果你想运行另一个怎么办?我知道它与Python方法解析顺序(MRO)有关.
我正在运行Python 2.5,因此这个问题可能不适用于Python 3.当您使用多重继承创建钻石类层次结构并创建派生最多类的对象时,Python会执行Right Thing(TM).它调用派生最多类的构造函数,然后调用从左到右列出的父类,然后是祖父母.我熟悉Python的MRO ; 那不是我的问题.我很好奇从super返回的对象实际上如何管理与父类中的super调用正确的顺序进行通信.考虑这个示例代码:
#!/usr/bin/python
class A(object):
def __init__(self): print "A init"
class B(A):
def __init__(self):
print "B init"
super(B, self).__init__()
class C(A):
def __init__(self):
print "C init"
super(C, self).__init__()
class D(B, C):
def __init__(self):
print "D init"
super(D, self).__init__()
x = D()
Run Code Online (Sandbox Code Playgroud)
代码做直观的事情,它打印:
D init
B init
C init
A init
Run Code Online (Sandbox Code Playgroud)
但是,如果你在B的init函数中注释掉对super的调用,则不会调用A和C的init函数.这意味着B对super的调用在某种程度上意识到C在整个类层次结构中的存在.我知道super返回一个带有重载get运算符的代理对象,但是在D的init定义中super返回的对象如何将C的存在传达给B的init定义中super返回的对象?后续超级使用调用的信息是否存储在对象本身上?如果是这样,为什么不是超级而不是self.super?
编辑:Jekke非常正确地指出它不是self.super,因为super是类的属性,而不是类的实例.从概念上讲,这是有道理的,但在实践中,超级也不是班级的属性!您可以在解释器中通过创建两个类A和B来测试它,其中B继承自A,并且调用dir(B).它没有super或__super__属性.
我想知道什么时候使用Python 3 super()的味道.
Help on class super in module builtins:
class super(object)
| super() -> same as super(__class__, <first argument>)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我super()只使用了没有参数,它按预期工作(由Java开发人员).
问题:
super(type, obj)和何时super(type, type2)?Mother.__init__(...)吗?我在这里看了关于python的super()方法的其他问题,但我仍然觉得很难理解整个概念.
我也在查看pro python一书中的例子
引用的例子是
class A(object):
def test(self):
return 'A'
class B(A):
def test(self):
return 'B-->' + super(B, self).test()
class C(A):
def test(self):
return 'C'
class D(B, C):
pass
>>> A().test()
'A'
>>> B().test()
'B-->A'
>>> C().test()
'C'
>>> D().test()
'B-->C'
>>> A.__mro__
(__main__.A, object)
>>> B.__mro__
(__main__.B, __main__.A, object)
>>> C.__mro__
(__main__.C, __main__.A, object)
>>> D.__mro__
(__main__.D, __main__.B, __main__.C, __main__.A, object)
Run Code Online (Sandbox Code Playgroud)
为什么要做D().test()我们得到'B - > C'而不是'B - > A'的输出
书中的解释是
在最常见的情况下,包括此处显示的用法,super()接受两个参数:类和该类的实例.正如我们在此处的示例所示,实例对象确定将使用哪个MRO来解析结果对象上的任何属性.提供的类确定该MRO的子集,因为super()仅使用在提供的类之后发生的MRO中的那些条目.
我仍然觉得解释有点难以理解.这可能是一个可能的重复,并且已经多次询问与此类似的问题,但如果我理解了这一点,我可能能够更好地理解其他问题.