Search code examples
pythonpython-class

How to run self referenced method from dictionary in python class?


So, is there a method to define self referencing dictionary of lambda functions which can be used to call different methods based upon the keys? Consider a small example of what is intended?

class A:
    d = {
        "add": lambda p1, p2: self.add(p1, p2),
        "minus": lambda p1, p2: self.minus(p1, p2),
        "multiply": lambda p1, p2: self.multiply(p1, p2),
        "divide": lambda p1, p2: self.divide(p1, p2)
    }
    def add(self, p1, p2):
        return p1+p2
    def minus(self, p1, p2):
        return p1-p2
    def multiply(self, p1, p2):
        return p1*p2
    def divide(self, p1, p2):
        return p1/p2

If I try the following:

a = A()
a.d["add"](1,2)

The above line throws an error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in <lambda>
NameError: name 'self' is not defined

What can be the best method to handle this?


Solution

  • In this case, your add, minus, etc. methods can be static, hence not require the instance of A, so your lambdas would be "add": lambda p1, p2: A.add(p1, p2), etc:

    class A:
        d = {
            "add": lambda p1, p2: A.add(p1, p2),
            "minus": lambda p1, p2: A.minus(p1, p2),
            "multiply": lambda p1, p2: A.multiply(p1, p2),
            "divide": lambda p1, p2: A.divide(p1, p2)
        }
    
        @staticmethod
        def add(p1, p2):
            return p1+p2
    
        @staticmethod    
        def minus(p1, p2):
            return p1-p2
    
        @staticmethod
        def multiply(p1, p2):
            return p1*p2
    
        @staticmethod
        def divide(p1, p2):
            return p1/p2
    

    As your d dictionary is static (class field) you can't call the instance methods. You could if you initialized it in the __init__ of A:

    class A:
        def __init__(self):
            self.d = {
                "add": lambda p1, p2: self.add(p1, p2),
                "minus": lambda p1, p2: self.minus(p1, p2),
                "multiply": lambda p1, p2: self.multiply(p1, p2),
                "divide": lambda p1, p2: self.divide(p1, p2)
            }
        def add(self, p1, p2):
            return p1+p2
    
        def minus(self, p1, p2):
            return p1-p2
    
        def multiply(self, p1, p2):
            return p1*p2
    
        def divide(self, p1, p2):
            return p1/p2
    

    In both cases

    a = A()
    a.d["add"](1,2)
    

    would work.