首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python超级旁路MRO

Python超级旁路MRO
EN

Stack Overflow用户
提问于 2014-02-25 19:20:36
回答 3查看 1K关注 0票数 1

我继承了一个类,并覆盖了一个也是从基类继承的方法。但是问题是,中间方法创建了一个异常,我希望通过调用第一个声明的方法来绕过这个异常。是否有一种方法来指定忽略第二个调用的mro

一个例子可以是:

代码语言:javascript
复制
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:类似于类BaseB(Base,BaseA)的东西可以工作吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-02-25 19:26:21

通常情况下,----您将修复该方法。

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

代码语言:javascript
复制
class BaseB(BaseA):
    def __init__(self):
        res = super(BaseA, self).__init__()

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

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

代码语言:javascript
复制
class BaseB(BaseA):
    def __init__(self):
        res = Base.__init__(self)

完全绕过任何MRO搜索。

票数 6
EN

Stack Overflow用户

发布于 2014-02-25 19:29:57

解决这个问题的正确方法是创建一个新的类层次结构,它用一个改进的实现覆盖违规的方法。不过,如果你坚持要进行黑客活动,这可能就是你想要的:

代码语言:javascript
复制
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实现。

然而,当涉及钻石继承时,这可能会做错误的事情。考虑:

代码语言:javascript
复制
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()

产出如下:

代码语言:javascript
复制
initing BaseD
initing BaseB
initing Base
<__main__.BaseD object at 0x7f1e693a0110>

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

代码语言:javascript
复制
>>> print [cls.__name__ for cls in BaseD.mro()]
['BaseD', 'BaseB', 'BaseC', 'BaseA', 'Base', 'object']
票数 2
EN

Stack Overflow用户

发布于 2014-02-25 19:29:44

不如就这样

Base.__init__(self)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22024069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档