0

My primary goal was to have a dictionary to select method to run. It was easy to do per this suggestion. But now I am somehow blocked on using the inheritance concept to call child overridden method.

class A():
    def sum(self, id: int):
        return 1

    def multiply(self, id: int):
        return 2

    def process(self, type: str, id: int):
        callable_method = self.__dispatcher.get(type)
        return callable_method(self, id) # Runs
        #callable_method(id)      # Doesnt work with my object, says parameter mismatch
        #self.callable_method(id) # Doesn't Work obviously as there is no callable method in self

    __dispatcher = { "+": sum,  "*": multiply  } 

class B(A):
    def process(self, type: str, id: int):
        return super(B, self).process(type, id)

    def multiply(self, id: int):
        return 3

# main class call:
    ob = B()
    ob.process("*", 0)  # This is returning 2 instead of 3

The above overriding works perfectly well if I dont use the dictionary and method references and directly use the method in parent's process() like self.multiply(id)

I might have an idea why this is not working but is there a way to make this work in Python?

Note:

  • Dont want to use exec() , eval() due to security issues
  • I'm not trying to write a calculator, actual problem is related to software design
  • using Python 3.8
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
pxm
  • 1,611
  • 2
  • 18
  • 34

1 Answers1

0

I think it's because A.__dispatcher is defined when A is first defined, and A.__dispatcher['*'] is a reference to A.multiply. You instead want something like

def __init__(self):
   self.__dispatcher = {'*': self.multiply}

Alternatively,

def get_dispatcher(self):
   return {'*': self.multiply}

and you use self.get_dispatcher() in place of __dispatcher

Kevin Wang
  • 2,673
  • 2
  • 10
  • 18
  • This worked and using self.func_name as values in dictionary even saved me from passing the self reference again. Thanks. – pxm May 12 '23 at 14:58