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

时间:2016-07-30 09:27:36

标签: python

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()

我试图获得[senario1]:

foo2
A - foo

但得到了[senario2]:

foo2
B - foo

代替。

我找到the explanation,但我想知道是否有一种方法可以在不改变类foo中方法A的名称的情况下产生[senario1]?

2 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是在foo上致电A并手动将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()

这样您就可以在foo上致电A。如果此foo会调用self.foo(),则会再次调用B的foo方法。

答案 1 :(得分:1)

正如Leon指出的那样,您可以通过foo对显式调用进行硬编码并将实例对象作为参数传递来简单地访问A类中的A.foo方法,但是正如Rawing所说的那样#39;不是很好的解决方案。实际上它是错误的课堂设计的例子。为什么呢?

  1. 想象一下,在一个更大的项目中,您将在数百个地方通过A.foo使用显式调用。现在,尝试将您的A课程重命名为MagicUnicorn课程。

  2. 这是违反直觉的。如果您从foo中的A覆盖B方法,那么在99.9999%的情况下不需要foo A,因为必须有覆盖的理由它

  3. 更好的解决方案,而不是使用显式调用,将重命名foo中的B(正如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()