Home > database >  Passing a function method into a class in python:
Passing a function method into a class in python:

Time:01-28

I would like to create a method inside a class that gets a variable and a function as input arguments and return a new value. In below example the arbitrary function can be max, min, mean, or ...:

import pandas as pd
df = pd.DataFrame( {'col1': [1, 2], 'col2': [4, 6]})
df.max(axis=1), df.min(axis=1), df.mean(axis=1)  # sample of methods that I would like to pass

I would like to do similar through a method inside a class. My attempt so far that does not work:

class our_class():
    def __init__(self, df):
        self.df = df
    
    def arb_func(self, func):
        return self.df.func()

ob1 = our_class(df)
ob1.arb_func(max(axis=1))

Any suggestions appreciated.

PS: It is a toy problem here. My goal is to be able to get a data frame and do arbitrary number of statistical analysis on it later. I do not want to hardcode the statistical analysis and let it change later if needed.

CodePudding user response:

You could try this:

class our_class():
    def __init__(self, df):
        self.df = df
    
    def arb_func(self, func):
        return func(self.df)

You could then use it like this:

ob1 = our_class(df)
ob1.arb_func(lambda x: x.max(axis=1))

CodePudding user response:

I assume the OP is trying to generate some generic coding interface for educational purposes?

Here a suggestion (which in my opinion is actually making the usage way more complex than necessary, as many other users have already noted in their questions/comments):

from functools import partial
import pandas as pd

df = pd.DataFrame({"a": [1, 2, 3]})

class our_class():
    def __init__(self, df):
        self.df = df
    
    def arb_func(self, func: str, **kwargs):
        return partial(getattr(pd.DataFrame, func), **kwargs)(df)

ob1 = our_class(df)
print(ob1.arb_func("max", axis=1))
0    1
1    2
2    3
dtype: int64


print(ob1.arb_func("max", axis=0))
a    3
dtype: int64

CodePudding user response:

You can pass the method name as a string (not a function object), create an expression with the help of f-string and evaluate it:

class our_class():
    def __init__(self, df):
        self.df = df
    
    def arb_func(self, func):
        return eval(f"self.df.{func}")

ob1 = our_class(df)
ob1.arb_func("max(axis=1)")
  •  Tags:  
  • Related