【问题标题】:Python recursive method calls with super使用 super 的 Python 递归方法调用
【发布时间】:2014-03-11 22:28:05
【问题描述】:

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

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。

问题:让“super(B, self).f()”把self当作类A,递归调用A.f(),然后返回B.f( ) 打印“世界?”

谢谢。

【问题讨论】:

    标签: python super


    【解决方案1】:

    我看到这项工作的唯一方法是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")
    

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

    【讨论】:

    • 我同意更好的设计是更改 A 中的实现。在这种情况下,我无法更改 A 有几个原因;希望通过仅更改 B 找到仍然可以工作的东西。不过,感谢您的回答。
    • @Max:添加了骇人听闻的路线:谎报self的班级。
    • 你说得对,这太可怕了。也许我会在这里寻求更好的选择......非常感谢!
    • 似乎几乎不值得为已经如此讨厌的东西争论不休,但你不应该保存并恢复__class__ 的原始值,以防它最初不是B 吗? :-)
    • @SteveJessop:确实。
    猜你喜欢
    • 2016-06-27
    • 2023-04-10
    • 1970-01-01
    • 2018-05-27
    • 2021-12-08
    • 2023-01-07
    • 1970-01-01
    • 2014-07-07
    相关资源
    最近更新 更多