我有一个继承的类,并复盖了一个也从基类继承的方法。但问题是,中间方法创建了一个异常,我想通过调用第一个声明的方法来绕过它。有没有办法指定给 mro 这忽略了第二个电话?

一个例子可能是:

class Base(object):
     def __init__(self):
         res = "Want this"
         print res

class BaseA(Base):
      def __init__(self):
          res = super(BaseA, self).__init__()
          res = "Not this"
          print res

class BaseB(BaseA):
      def __init__(self):
          res = super(BaseB, self).__init()
          #At this poing res is "Not this"
          #The desire is that it would be "Want this"
          print res

非常感谢!

PD:像class BaseB(Base,BaseA)这样的东西可以工作?

有帮助吗?

解决方案

通常情况下 你会修复那个方法。

然而,第一个论点是 super() 是开始搜索下一个方法的地方 .通常这将是当前类,但您也可以传入基类:

class BaseB(BaseA):
    def __init__(self):
        res = super(BaseA, self).__init__()

这里, super() 采取的MRO type(self),发现 BaseA 在那个MRO中,并寻找下一个实现的类 __init__.

绕过问题的另一种方法 __init__ 方法就是只调用unbound方法on Base 直接:

class BaseB(BaseA):
    def __init__(self):
        res = Base.__init__(self)

完全绕过任何MRO搜索。

其他提示

解决这个问题的正确方法是创建一个新的类层次结构,用改进的实现复盖违规的方法。如果你坚持hackery虽然,这可能是你想要的:

class BaseB(BaseA):
      def __init__(self):
          res = super(BaseA, self).__init()
          #At this poing res is "Not this"
          #The desire is that it would be "Want this"
          print res

请注意,我要求关于BaseA的超级实现,这意味着BaseA实现从未被使用。


然而,这 可以 当涉及钻石继承时,做了错误的事情。考虑一下:

class Base(object):
    def __init__(self):
        print 'initing Base'

class BaseA(Base):
    def __init__(self):
        print 'initing BaseA'
        res = super(BaseA, self).__init__()

class BaseB(BaseA):
    def __init__(self):
        print 'initing BaseB'
        res = super(BaseA, self).__init__()

class BaseC(BaseA):
    def __init__(self):
        print 'initing BaseC'
        res = super(BaseC, self).__init__()

class BaseD(BaseB, BaseC):
    def __init__(self):
        print 'initing BaseD'
        res = super(BaseD, self).__init__()

print BaseD()

输出为 :

initing BaseD
initing BaseB
initing Base
<__main__.BaseD object at 0x7f1e693a0110>

BaseC 被跳过了,尽管这不是我们想要的。这是因为 BaseC 介于两者之间 BaseBBaseA 在方法解析顺序中,所以当我们从 BaseBBaseA 我们无意中忽略了 BaseC.

>>> print [cls.__name__ for cls in BaseD.mro()]
['BaseD', 'BaseB', 'BaseC', 'BaseA', 'Base', 'object']

怎么回事

Base.__init__(self)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top