Python超级旁路MR

2024-06-13 13:59:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个继承的类,重写了一个同样从基类继承的方法。但问题是middle方法创建了一个异常,我想通过调用第一个声明的方法来绕过它。有没有一种方法可以指定给忽略第二个调用的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

非常感谢

警察局: 类BaseB(Base,BaseA)之类的东西可以工作吗?在


Tags: 方法selfbaseinitisdefnotres
3条回答

不如就这样

Base.__init__(self)

解决这个问题的正确方法是创建一个新的类层次结构,用改进的实现覆盖有问题的方法。如果你坚持黑客攻击,这可能是你想要的:

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实现。在


然而,当涉及到钻石继承时,这会导致错误的结果。考虑:

^{pr2}$

输出为:

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

BaseC被跳过,尽管这不是我们想要的。这是因为BaseC在方法解析顺序上介于BaseB和{}之间,所以当我们从BaseB跳到{}时,我们无意中忽略了BaseC。在

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

通常情况下,您应该修复该方法。在

但是,super()的第一个参数是从开始搜索下一个方法的地方。通常这是当前类,但也可以传入基类:

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

这里,super()获取type(self)的MRO,在该MRO中找到{},并寻找下一个实现__init__的类。在

另一种绕过有问题的__init__方法的方法是直接调用Base上的unbound方法:

^{pr2}$

完全绕过任何MRO搜索。在

相关问题 更多 >