Python 运行子方法而不是父方法';s
我有以下类继承模式:Python 运行子方法而不是父方法';s,python,class,inheritance,Python,Class,Inheritance,我有以下类继承模式: object类B中的setup方法调用super,因此它从A调用setup方法。。。以下是方法的执行顺序: Z.setup() B.setup() A.setup (via super) B._configure B.configured.append("B") B.setup.append("A") B._configure B.configured.append("B") B.set_up.ap
object类B
中的setup
方法调用super
,因此它从A
调用setup
方法。。。以下是方法的执行顺序:
Z.setup()
B.setup()
A.setup (via super)
B._configure
B.configured.append("B")
B.setup.append("A")
B._configure
B.configured.append("B")
B.set_up.append("B")
这意味着Z.setup
通过继承调用B.setup
,继承调用A.setup
通过super
,继承调用B.\u configure
B.setup
再次调用B.\u configure
并在追加后返回
希望这一点(或多或少)能说明问题
更新:这里对发生的事情做一点解释:您正在定义一个类Z
,它有一个公共方法设置
和一个私有方法\u configure
。这些方法不是在Z
类中定义的,而是在其父类B
中定义的。但由于继承,您仍然可以调用Z.setup
和Z.\u configure
现在,Z.setup
方法使用B
类中的定义来工作。这将调用super
,以便调用A.setup
中定义的代码,同时仍处于Z
状态,因此当调用方法\u configure
时,将使用哪个定义?由于我们是Z
(也就是说,self
是Z
的一个实例),将调用的方法是Z.\u configure
,因为继承就是这样做的
再次查看代码:您正在B
中覆盖\u configure
方法,该方法首先在A
中定义。由于在B.\u configure
中没有调用super
,A.\u configure
将永远不会被调用,如果对象是从A
继承的类的实例
TL;DR:如果B
定义\u configure
而不调用super,则不能从Z
调用A.\u configure
。这就是遗产。如果要调用A.configure
,请不要覆盖B
中的方法或使用super
希望这有帮助!:) 类B
中的setup
方法调用super
,因此它从A
调用setup
方法。。。以下是方法的执行顺序:
Z.setup()
B.setup()
A.setup (via super)
B._configure
B.configured.append("B")
B.setup.append("A")
B._configure
B.configured.append("B")
B.set_up.append("B")
这意味着Z.setup
通过继承调用B.setup
,继承调用A.setup
通过super
,继承调用B.\u configure
B.setup
再次调用B.\u configure
并在追加后返回
希望这一点(或多或少)能说明问题
更新:这里对发生的事情做一点解释:您正在定义一个类Z
,它有一个公共方法设置
和一个私有方法\u configure
。这些方法不是在Z
类中定义的,而是在其父类B
中定义的。但由于继承,您仍然可以调用Z.setup
和Z.\u configure
现在,Z.setup
方法使用B
类中的定义来工作。这将调用super
,以便调用A.setup
中定义的代码,同时仍处于Z
状态,因此当调用方法\u configure
时,将使用哪个定义?由于我们是Z
(也就是说,self
是Z
的一个实例),将调用的方法是Z.\u configure
,因为继承就是这样做的
再次查看代码:您正在B
中覆盖\u configure
方法,该方法首先在A
中定义。由于在B.\u configure
中没有调用super
,A.\u configure
将永远不会被调用,如果对象是从A
继承的类的实例
TL;DR:如果B
定义\u configure
而不调用super,则不能从Z
调用A.\u configure
。这就是遗产。如果要调用A.configure
,请不要覆盖B
中的方法或使用super
希望这有帮助!:) 我终于明白了,必要的魔法叫做or
解决方案非常简单,只需在配置方法的名称中使用两个下划线即可。当Python看到这种有趣的命名方法(或其他属性)时,它会悄悄地将其重命名为\u A\u configure
,这样即使用户(无意或无意)重写了正确的方法,也会调用它
(直到现在,我还以为“两个下划线”是为Python内部保留的,谦虚地一直避免使用它们……)
固定代码:
#!/usr/bin/python
class A(object):
def __init__(self):
self.configured = []
self.set_up = []
def __configure(self):
self.configured.append("A")
def setup(self):
self.__configure()
self.set_up.append("A")
class B(A):
def __configure(self):
self.configured.append("B")
def setup(self):
super(B, self).setup()
self.__configure()
self.set_up.append("B")
class Z(B):
pass
if __name__ == "__main__":
z = Z()
z.setup()
print "configured: %s" % z.configured
print "set up: %s" % z.set_up
返回所需的值
me@here:~$ ./t.py
configured: ['A', 'B']
set up: ['A', 'B']
me@here:~$
最后我得到了它,必要的魔法叫做or
解决方案非常简单,只需在配置方法的名称中使用两个下划线即可。当Python看到这种有趣的命名方法(或其他属性)时,它会悄悄地将其重命名为\u A\u configure
,这样即使用户(无意或无意)重写了正确的方法,也会调用它
(直到现在,我还以为“两个下划线”是为Python内部保留的,谦虚地一直避免使用它们……)
固定代码:
#!/usr/bin/python
class A(object):
def __init__(self):
self.configured = []
self.set_up = []
def __configure(self):
self.configured.append("A")
def setup(self):
self.__configure()
self.set_up.append("A")
class B(A):
def __configure(self):
self.configured.append("B")
def setup(self):
super(B, self).setup()
self.__configure()
self.set_up.append("B")
class Z(B):
pass
if __name__ == "__main__":
z = Z()
z.setup()
print "configured: %s" % z.configured
print "set up: %s" % z.set_up
返回所需的值
me@here:~$ ./t.py
configured: ['A', 'B']
set up: ['A', 'B']
me@here:~$
您的输出显示它调用了B.\u configure
两次,而不是A.\u configure
。这看起来与预期完全一样-通常情况下,会调用子方法,除非您使用的是super
。您的输出显示它调用了B.\u configure
两次,不是A.\u configure
。这看起来像是完全按照预期工作的-一般来说,调用子方法,除非您使用super
。我想问题是为什么A.setup
调用B.\u configure
而不是A.\u configure
。因为