Domanda

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.

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top