使用super进行Python递归方法调用

时间:2014-03-11 22:28:06

标签: python super

我正在使用一个依赖于递归方法调用的库:

class A(object):
    def __init__(self):
        self.foo = None

    def f(self):
        if not self.foo:
            print("Hello")
            self.foo = 100
            self.f()

我想在使用原始实现时覆盖方法f():

class B(A):
    def f(self):
        super(B, self).f()
        print("World")

这样,我希望得到:

Hello
World

相反,我明白了:

Hello
World
World

我理解这是因为A类中的原始代码调用了self.f(),它找到了B.self。

问题:最具Pythonic的方式是什么" super(B,self).f()"将self视为A类,递归调用A.f(),然后返回B.f()打印" World?"

感谢。

1 个答案:

答案 0 :(得分:5)

我能看到这项工作的唯一方法是A.f()不使用self.f(),而是使用A.f(self)代替。

更好的设计是A.f()将递归调用委托给单独的方法:

class A(object):
    def __init__(self):
        self.foo = None

    def f(self):
        self._f_recursive()

    def _f_recursive(self):
        if not self.foo:
            print("Hello")
            self.foo = 100
            self._f_recursive()

如果你唯一的选择在于B,那么除了不要覆盖f() 之外,就是暂时对这个类撒谎。 这不是Pythonic或推荐,但它会起作用:

class B(A):
    def f(self):
        try:
            self.__class__, cls = A, self.__class__
            A.f(self)
        finally:
            self.__class__ = cls
        print("World")

要明确这一点:这不是线程安全的,也不是解决这个问题的正确方法。