Python:从子方法中调用父方法中的子方法

时间:2018-08-29 18:17:54

标签: python python-3.x inheritance

我希望能够从使用该父类中的第二个方法的父类中回收方法。但是,第二个方法在子类中被覆盖。我希望回收的父方法在从子类中调用时使用新的重写的第二个方法。我希望它如何工作的一个示例有望使这一点更加清楚:

<div class="cbCollapseRow">
  <button class="cbCollapse"></button>
  <h2>Sample 1</h2>
</div>
<div class="content">
  <p>Lorem ipsum dolor sit amet</p>
</div>

<button class="cbCollapse"></button>
<div class="content">
  <p>Lorem ipsum dolor sit amet</p>
</div>

<div class="cbCollapseRow">
  <button class="cbCollapse"></button>
  <h2>Sample 3</h2>
</div>
<div class="content">
  <p>Lorem ipsum dolor sit amet</p>
</div>

在python3中有可能吗?还是将调用父级的方法2也使用父级的方法1?我希望重用父类的大部分内容,因为子类仅在几个方面有所不同。像这样在父类中嵌套的方法使它更加通用。

谢谢!

编辑:我忘了用简单的代码对其进行测试!如果有人在想,它的确像我想要的那样工作!

2 个答案:

答案 0 :(得分:1)

是的,这可以按您想要的方式工作。

您可以自己轻松地对此进行测试。除非您传入0和1,否则它们是平方还是立方应该很明显。

并且,在不太明显的情况下,只需在Child.method1Parent.method1上添加调试器断点,看看哪个命中了。或将print(f'Child1.method({self}, {num})')添加到方法中,看看它是否被打印出来。


如果您来自使用C ++ OO语义而不是Smalltalk OO语义的另一种语言,则可能会这样思考:每种方法始终是虚拟的。

  • __init__呼叫是否虚拟?是的。
  • 如果您在__init__期间调用方法怎么办?是的。
  • 如果您在super调用中调用方法怎么办?是的。
  • @classmethod呢?是的。
  • 如果……怎么办?是的。

唯一的例外是当您竭尽全力明确告诉Python not 进行虚拟函数调用时:

  • super()的调用使用MRO链中下一类的实现,因为这就是super的重点。
  • 如果您获取父对象的绑定方法并像Parent.method1(self, num)那样调用它,显然会得到Parent.method1,因为这就是绑定方法的重点。
  • 如果您深入研究类字典并手动运行描述符协议,显然您会得到手动进行的一切。

如果您不想尝试用Java来理解Python,而只是想更深入地了解Python,那么您需要了解的是调用self.method1(i)时发生的事情。

首先,self.method1不知道或不在乎您要如何称呼它。这是一个属性查询,就像self.name这样。

Descriptor HOWTO中描述了Python解决此问题的方式,但是过分简化的版本看起来像这样:

  • self.__dict__是否有任何名为method1的东西?不。
  • type(self).__dict__是否有任何名为method1的东西?是。
    • 返回type(self).__dict__['method1'].__get__(self)

如果第二次查找失败,Python将遍历type(self).mro()并对每个对象进行相同的测试。但是在这里,这不会出现。 type(self)对于Child的实例始终将是Child,并且Child.__dict__['method1']存在,因此它将Child.method绑定到self,并且结果就是self.method1的意思。

答案 1 :(得分:1)

简短的回答:是的。 刚刚尝试对带有打印内容的代码进行了稍微修改。

class Parent:
    def method1(self):
        print("Parent method1")

    def method2(self):
        print("Parent method2")
        self.method1()


class Child(Parent):
    def method1(self):
        print("Child method1")

    def method2(self):
        print("Child method2")
        super().method2()


c = Child()
c.method2()

这是输出:

Child method2

Parent method2

Child method1

如您所见,方法1是子级方法。