0

Mostly well-known, here's how to call a super class's overloaded method f.

class Base:
    def f(self, *args):
        print(f"BASE method invoked.")

class Inherit(Base):
    def f(self, *args):
        super(Inherit, self).f(*args) # Calling overloaded method

However, if I don't know f, and instead, it's passed as an argument func, how shall I rewrite the super... statement? An example context is to define a decorator that applies some uniform operation to all the overloaded functions.

Clarification and more details:

In the following example, I have a Base class that is a library not owned by me. It has severals (20+) methods f, g etc that internally makes some remote procedure calls (RPC). The library documentation suggests subclassing the Base to use it.

For debugging purpose, I would like to record a log every time a RPC is called. So I'd like to make a uniform function decorator log_rpc for all the RPC methods.

def log_rpc(func):
    """This does not work"""
    def new_func(self, *args, **kwargs):
        print(f"Invoking RPC {METHODNAME} with parameters: {locals()}")
        super(CLASSNAME, self).METHODNAME(*args, **kwargs) # Two issues here.
    return new_func

class Base: # This is provided by some library
    def f(self, *args):
        # rpc_client.f() # make some rpc calls.
        print(f"BASE method invoked.")

    def g(self, *args):
        # rpc_client.g() # make some rpc calls.
        print(f"BASE method invoked.")

class Inherit(Base): # My own code subclassing the library
    @log_rpc
    def f(self, *args):
        """function body will be ignored by the decorator."""
        pass

    @log_rpc
    def g(self, *args):
        """function body will be ignored by the decorator."""
        pass

Inherit().f()

However, when making a generic decorator independent of Inherit class or method f, there are two emerging issues

  1. How do I figure out the CLASSNAME in the decorator? Since the decorator is invoked during the class Inherit is being constructed, I can't use module's __qualname__ to retrieve the Inherit class object.
  2. How do I figure out the METHODNAME in the decorator?

What I have searched so far:

  • A similar question thread but does not have a solution.
  • Python documentation about super and descriptor mechanism.
Shichu Zhu
  • 311
  • 3
  • 15
  • Are you aware that you could get the same effect as your `call_base` by just not overriding the method at all? – user2357112 Jul 01 '20 at 07:40
  • Yes. The example is for simplicity only. I can certainly add more logic around invoking the base methods. – Shichu Zhu Jul 01 '20 at 07:43
  • Could you provide some actual context of the problem you're trying to solve? It's not clear to me why you'd want to do this. – jonrsharpe Jul 01 '20 at 07:46
  • Some more realistic context: Let's say we'd like to record each time an overloaded function is invoked. I can add a `print(f"overloaded method {METHODNAME} invoked")` in the decorator. The benefit of this is I only need to write once in the decorator, instead of 100 times in each overloaded function. – Shichu Zhu Jul 01 '20 at 07:50
  • You might also reconsider this design: https://www.martinfowler.com/bliki/CallSuper.html – Karl Knechtel Jul 01 '20 at 07:55

0 Answers0