【问题标题】:How to call methods which are present in right side defined class. Python inheritance. multiple inheritance. Dimond scenario python inheritance如何调用右侧定义的类中存在的方法。 Python 继承。多重继承。 Dimond场景python继承
【发布时间】:2017-12-03 11:34:51
【问题描述】:

我有一个继承自其他两个类的类。当我从子类调用方法时,它总是调用类定义中提到的左侧方法。

我知道 Python 的这种工作方式。它首先检查左侧类中的方法,然后检查右侧类中的方法。

但现在我无法更改我的子类定义。 请帮帮我,我怎样才能调用“第二”类中存在的相同方法。

我对 Python 有点陌生。 使用 python 2.7

class First(object):
    def get_details(self):
        print "This method gets called every time"
        print "I can't change my Child class structure" 

class Second(object):
    def get_details(self):
        print "But I want to call the same method of this class.. "
        print "Please let me know what can I do? How do I call method of second inherited class" 

class Child(First, Second):
    pass


child_obj = Child()
child_obj.get_details()

【问题讨论】:

    标签: python python-2.7 oop multiple-inheritance


    【解决方案1】:

    你可以直接调用它:

    Second.get_details(child_obj)
    

    或者使用.mro()获取方法解析顺序并选择第二个父类:

    Child.mro()[2].get_details(child_obj)
    

    方法解析顺序显示了 Python 用于查找方法的类的搜索顺序:

    >>> Child.mro()
    [__main__.Child, __main__.First, __main__.Second, object]
    

    一旦在此列表中找到get_details(),它就会停止并使用它。

    我建议将这个逻辑隐藏在Child的方法中:

    class Child(First, Second):
    
        def get_details_second_1(self):
            """Option 1"""
            return Second.get_details(self)
    
        def get_details_second_2(self):
            """Option 2"""
            return Child.mro()[2].get_details(self)
    
    child_obj = Child()
    child_obj.get_details_second_1()
    child_obj.get_details_second_2()
    

    【讨论】:

    • 第一个适用于这个例子。我不知道“mro()”以及它是如何工作的。无论如何感谢您的帮助,我会搜索 mro()
    • 如果你想检查一个类的基类,__bases__ 是一种更安全的方法。如果First 的父母不是objectmro()[2] 很容易成为祖父母而不是第二基地。
    【解决方案2】:

    您始终可以通过在要使用其定义的方法的类上调用方法来直接调用方法:

    Second.get_details(child_obj)
    

    对于您可能不知道父类但想要篡改method resolution order 的更一般情况,您可以使用该类的mro 方法检查所述顺序:

    Child.mro()
    # [<class 'Child'>, 
    #  <class 'First'>, 
    #  <class 'Second'>, 
    #  <class 'object'>]
    

    你可以故意跳过父类:

    Child.mro()[2].get_details(child_obj)
    

    或者颠倒顺序:

    for klass in reversed(Child.mro()):
        if hasattr(klass, 'get_details'):
            klass.get_details(child_obj)
            break
    

    【讨论】:

    • 感谢您的回答。我明白了。
    猜你喜欢
    • 1970-01-01
    • 2013-12-25
    • 2018-03-10
    • 1970-01-01
    • 2020-12-18
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多