[英]Python: Call child method inside parent method from child method
我希望能够从在该父类中使用第二个方法的父类中回收方法。 但是,第二个方法在子类中被覆盖。 我希望回收的父方法在从子类中调用时使用新的重写的第二个方法。 我希望它如何工作的一个示例有望使这一点更加清楚:
class Parent:
def method1(self, num):
return num**2
def method2(self, list_size):
return [self.method1(i) for i in range(list_size)] #List of squares
class Child(Parent):
def method1(self, num): #Overrides corresponding parent method
return num**3
def method2(self, list_size):
return super().method2(list_size) #Returns a list of cubes using child's method 1.
在python3中可以吗? 还是将调用父级的方法2也使用父级的方法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
如您所见,使用的method1是子级方法1。
是的,这可以按您想要的方式工作。
您可以自己轻松测试。 除非您传入0和1,否则它们是平方还是立方的,应该很明显。
并且,在不太明显的情况下,只需将调试器断点添加到Child.method1
和Parent.method1
然后查看哪个Parent.method1
。 或将print(f'Child1.method({self}, {num})')
到方法中,看看是否可以打印出来。
如果您来自使用C ++ OO语义而不是Smalltalk OO语义的另一种语言,则可能会这样考虑:每个方法始终是虚拟的。
__init__
调用是虚拟的吗? 是。 __init__
期间调用方法怎么办? 是。 super
调用中调用方法怎么办? 是。 @classmethod
呢? 是。 唯一的例外是当您竭尽全力明确告诉Python 不要进行虚函数调用时:
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()
并对每个对象进行相同的测试。 但是在这里,这不会出现。 对于Child
的实例, type(self)
始终将为Child
,并且Child.__dict__['method1']
存在,因此它将Child.method
绑定到self
,结果就是self.method1
含义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.