简体   繁体   English

Python super:调用一个基类方法,该方法包含另一个由派生类覆盖的基类方法

[英]Python super: calling a base class method which contains another base class method that is overriden by derived class

class A(object):
    def foo(self):
        print "A - foo"
    def foo2(self):
        print "foo2"
        self.foo()

class B(A):
    def foo(self):
        print "B - foo"
    def foo2(self):
        super(B, self).foo2()

B().foo2()

I was trying to get [senario1]: 我正在尝试获取[senario1]:

foo2
A - foo

but got [senario2]: 但是得到了[senario2]:

foo2
B - foo

instead. 代替。

I found the explanation , but I am wondering if there is a way that yields [senario1] without changing the name of method foo in class A ? 我找到了解释 ,但是我想知道是否有一种方法可以在不更改类A foo方法名称的情况下产生[senario1]吗?

One way to do this is to call foo on A and pass self to it by hand: 一种实现方法是在A上调用foo并将其self传递给它:

class A(object):
    def foo(self):
        print("A - foo")
    def foo2(self):
        print("foo2")
        A.foo(self)

class B(A):
    def foo(self):
        print("B - foo")
    def foo2(self):
        super(B, self).foo2()

B().foo2()

This way you will always call foo on A . 这样,您将始终在A上调用foo If this foo would call self.foo() , if would again call B s foo method. 如果此foo将调用self.foo() ,则再次调用B的foo方法。

As Leon pointed out you could simply access the foo method inside the A class by hardcoding the explicit call via A.foo and passing instance object as argument, however as Rawing has stated it's not good solution. 正如Leon所指出的,您可以通过对A.foo的显式调用进行硬编码并将实例对象作为参数进行传递, A.fooA类内部简单地访问foo方法,但是正如Rawing所言,这不是一个好方法。 Actually it's example of wrong class design. 实际上,这是错误的类设计的示例。 Why? 为什么?

  1. Imagine that in a larger project you would use explicit calls via A.foo in hundreds of places. 想象一下,在一个更大的项目中,您将在数百个地方通过A.foo使用显式调用。 Now, try to rename your A class to MagicUnicorn class. 现在,尝试将您的A类重命名为MagicUnicorn类。

  2. It's counter-intuitive. 这是违反直觉的。 If you override the foo method from A in B then the foo from A is not needed in 99.9999% cases as there must be a reason to override it. 如果您从B A覆盖foo方法,则在99.9999%的情况下不需要Afoo ,因为必须有理由对其进行覆盖。

A better solution rather than using explicit calls would be to rename the foo in B (as Rawing has said): 与使用显式调用相比,更好的解决方案是将Bfoo重命名(如Rawing所说):

class A(object):
    def foo(self):
        print "A - foo"
    def foo2(self):
        print "foo2"
        self.foo()

class B(A):
    def unicorn_foo(self):
        print "B - foo"
    def foo2(self):
        super(B, self).foo2()

B().foo2()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM