Python使用super的递归方法调用

3 投票
1 回答
1200 浏览
提问于 2025-04-17 21:51

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

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。

问题:在 Python 中,最合适的方式是什么,让 "super(B, self).f()" 把 self 当作类 A,递归调用 A.f(),然后再返回到 B.f() 打印 "World"?

谢谢。

1 个回答

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()之外,暂时可以对类做一些“假装”。 这样做不符合 Python 的风格,也不推荐,但确实能奏效:

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

需要明确的是:这样做不是线程安全的,也不是处理这个问题的正确方法。

撰写回答