سؤال

I am working with a library that relies on a recursive method call:

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

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

I would like to override the method f() while using the original implementation:

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

This way, I hope to get:

Hello
World

Instead, I see:

Hello
World
World

I understand this is because the original code in class A calls self.f(), which finds B.self.

Question: What is the most Pythonic way to have "super(B, self).f()" treat self as class A, call A.f() recursively, and then return to B.f() to print "World?"

Thanks.

هل كانت مفيدة؟

المحلول

The only way I can see this work is for A.f() to not use self.f() but to use A.f(self) instead.

A better design is for A.f() to delegate the recursive call to a separate method:

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

If your only option lies in B, then apart from don't override f() then, is to lie about the class, temporarily. This is not Pythonic or recommended but it'll work:

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

To be clear about this: this is not thread-safe nor the proper way to deal with this.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top