Bobe Kryant
Bobe Kryant

Reputation: 2100

python *args and **kwargs

I have seen the previous stack overflow posts on this topic, but I am still unable to create use these two commands when I try to run my function. I have coded a demo example of a simple moving average that I would like to run through the args,kwargs command.

import numpy as np
def moving_average(data,lookback=7,SMA=True): #MA function
    if SMA==True:
        weights=np.repeat(1.0,lookback)/lookback
        smas=np.convolve(data,weights,'valid')
        return smas

Just running this function works as expected.

data=np.random.randn(100) #randomly 
moving_average(data,lookback=7,SMA=True) #this outputs the correct set of numbers

However the second I try to add args and kwargs it breaks down.

def test1(*args,**kwargs):
    return moving_average(data,lookback,SMA)
test1(data,lookback=7,SMA=True) #this returns an error, saying my global lookback is not defined

What exactly in the *args **kwargs logic am I getting wrong? Ive tried inputting both a tuple and a dictionary but neither of those seem to work.

Upvotes: 1

Views: 1481

Answers (4)

amitsin6h
amitsin6h

Reputation: 193

You can understand args and kwargs in python at PyMentor. Hope it helps you understand.

how to understand args and kwargs in python

Upvotes: -2

RemcoGerlich
RemcoGerlich

Reputation: 31250

def test1(*args,**kwargs):

Your function now has two local variables, args and kwargs. One holds the positional arguments that were passed in (as a tuple), the other the keyword arguments (as a dictionary).

return moving_average(data,lookback,SMA)

Here you use three variable names (data, lookback and SMA) that don't exist in your function, so you get an error.

You could have done

return moving_average(args[0], kwargs['lookback'], kwargs['SMA'])

But then your test1 function will only work with an exact call like test1(data,lookback=7,SMA=True). A call like test1(data, 7, True) won't work, as then the parameters are all in args, none in kwargs).

Your function could also pass on the parameters exactly as it received them:

return moving_average(*args, **kwargs)

That works, but there's no benefit to the test1 function, it just calls moving_average and returns its results, why not call moving_average directly.

Upvotes: 2

FamousJameous
FamousJameous

Reputation: 1585

In your example using *args and **kwargs:

def test1(*args,**kwargs):
    return moving_average(data,lookback,SMA)

data, lookback and SMA are no longer defined. It could be:

def test1(*args, **kwargs):
    return moving_average(args[0], kwargs['lookback'], kwargs['SMA'])

or

def test1(*args, **kwargs):
    return moving_average(*args, **kwargs)

The Python tutorial has a section that might help: Unpacking Argument Lists

Upvotes: 2

Moses Koledoye
Moses Koledoye

Reputation: 78546

Pass the *args and **kwargs to your function not the argument(s) and named argument(s):

def test1(*args,**kwargs):
    return moving_average(*args, **kwargs)

Upvotes: 2

Related Questions