If we look at your example:
def get_data(arg1, **kwargs): print arg1, arg2, arg3, arg4
There is a variable named arg1 in your get_data function namespace, but there is no variable named arg2 . therefore, you cannot reach a function or variable that is not in your namespace.
In fact, in your namespace; there is an arg1 variable and a dictionary object called kwargs . using the notation ** before kwargs (there is no kwargs value here, it could be something else.) tells your python compiler that kwargs is a dictionary, and all values ββin this dictionary will be evaluated as named parameters in your function definition.
Let's look at this example:
def myFunc(**kwargs): do something myFunc(key1='mykey', key2=2)
when you call myFunc with the named parameters key1 and key2 , your function definition acts like
def myFunc(key1=None, key2=None):
but with the exception! since myFunc do not have named parameters, the compiler does not know how to handle them directly, since you can pass any named parameter to your function.
So, your function accepts these named parameters in the dictionary, as you call your function:
myFunc({key1:'mykey', key2:2})
So your function definition gets these parameters in the dictionary. **kwargs defines your dictionary at this point, which also tells the compiler that any named parameters will be accepted (using the ** icons in front of kwargs)
def myFunc(**kwargs): print kwargs
will print
{key1:'mykey', key2:2}
So, in your example, you can use kwargs as a dictionary;
def myFunc(**kwargs): kwargs['arg2'] kwargs.get('arg3')
Hope this is not difficult (: