Search code examples
python-3.xclasspython-decorators

How to pass method name as an argument while calling another method?


I am writing a class wherein I want to use a metric to calculate the score. I should be able to pass the metric as an argument based on which I want to calculate a score. Here is the code I have written. Is there a better approach to solving this situation?

class A:

        def __init__(self, region):
           self.region = region
     
        def metric1(self, a, b):
            returns a*b
      
        def metric2(self, a, b, c):
            return self.metric1(a, b) + c

        def evaluate(self, metric, a, b, c = None):
            if metric = 'metric1':
                score = self.metric1(a,b)
            elif metric = 'metric2':
                score = self.metric2(a,b,c)
            return score[0]

obj1 = A('XYZ')
obj1.evaluate('metric2', a, b, c)

Furthermore, I want to write another method that would use the output of the evaluate method to do some other calculations. Is this the right approach to writing a class when we have this chain of outputs from previous methods used in subsequent methods? Or, can we leverage decorators here somehow?


Solution

  • You can access method inside a class by className.methodName (A.metric1) or object.methodName (obj1.metric1)

    class A:
    
        def __init__(self, region):
            self.region = region
        
        def metric1(self, a, b):
            return a*b
        
        def metric2(self, a, b, c):
            return self.metric1(a, b) + c
    
        def evaluate(self, metric, a, b, c = None):
            if metric == A.metric1:
                score = self.metric1(a,b)
            elif metric == A.metric2:
                score = self.metric2(a,b,c)
            return score
    
    obj1 = A('XYZ')
    print(obj1.evaluate(A.metric1, a=1, b=2)) # 2
    print(obj1.evaluate(A.metric2, a=1, b=2, c=3)) # 5
    

    My approach of writing such class.

    class A:
    
        def __init__(self, region, a, b, c=None):
            self.region = region
            self.a = a 
            self.b = b 
            self.c = c
        
        def metric1(self):
            return self.a * self.b
        
        def metric2(self):
            return A.metric1(self) + self.c
    
    obj1 = A('XYZ', 1, 2, 3)
    
    print(A.metric1(obj1)) # 2
    print(A.metric2(obj1)) # 5