0

I have a functions module that has some functions all with some common inputs, and others that are particular to them. e.g.

def func_a(time_series, window ='1D'):

def func_b(time_series, window ='1D', availability_history ): 

def func_c(time_series, window ='1D', max_lag=25, use_probability ='T'):

I am trying to run these functions in a loop as follows:

func_list = [func_a, func_b, func_c]
windows = ['1D', '5D']
params = ['', hist, (25, 'T')]

for i_func, func in enumerate(func_list):
    class_obj = class_X(A,B,func)

    for window in windows:
        args = (window, params[i_func]) # params is a list or tuple of other params for funcs e.g. 
        class_obj.run_func(args)

And in another module

class class_X(object):
    def __init__(self, a, b, func_to_run):
        self.a = a
        self.ts = b
        self.method = func_to_run

    def generate_output(self, *args):
        return self.method(self.ts, args) # time series is common and fixed for all, other params differ or change

The above code wouldn't work because I think the functions that I am calling need to be changed to make use of *argsrather than having fixed defined params.

I think *args is meant for functions where number of input params are not known, but I am trying to use it in a case where the number of input params is known, but varies across different functions in a loop.

Is there any fix for this where I don't have to modify the functions module and can still pass all the required params as a single object (e.g. list or tuple)?

EDIT-

macromoonshine's answer states I can use kwargs like this:

def generate_output(self, **kwargs):
    return self.method(self.ts, kwargs)

With this modification you can call generate_outputs() as follows:

x.generate_outputs( window ='1D', max_lag=25, use_probability ='T')

where xis an instance of your class X

Can this be enhanced so I can pass args other than time_series and window as a lookup value in a loop e.g.

x.generate_outputs( window ='1D', params[iloop])

where

params[iloop] = max_lag=25, use_probability ='T'

I tried doing this:

params = (30, "F")
x.generate_outputs( window, *params)

but get an error

TypeError: generate_output() takes 1 positional argument but 4 were given
1
  • 1
    look up keyword arguments. **kwargs Commented Nov 11, 2017 at 9:19

1 Answer 1

1

You can use the **kwargs instead which allows arbitrary keyword parameters. This should be easier than chinging each function. You have just to modify your generate_outputs() method in your code:

def generate_output(self, **kwargs):
    return self.method(self.ts, kwargs)

With this modification you can call generate_outputs() as follows:

x.generate_outputs(time_series, window ='1D', max_lag=25, use_probability ='T')

where xis an instance of your class X.

If you want to pass the kwargs from a dict instead named parameter, you have to prefix the dictionary variable with **. The adapted code should look like this:

params = [{max_lag: 35, use_probability: 'F'}, ... ]
TS= [1,2,3,4]

for i_func, func in enumerate(func_list):
    class_obj = class_X(TS, func)
    for window in windows:
        req_args = dict(params[i_func])
        req_args['window'] = 0
        class_obj.generate_output(**req_args)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, how can i pass the arguments other than time_series and window as something I lookup via a list/tuple etc. e.g. x.generate_outputs(time_series, window ='1D', params [i]) where params[i] = max_lag=25, use_probability ='T'
Sorry, you're right. I've adapted my post for this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.