I'm writing a function whose inner logic needs to know which optional keyword arguments the function was called with.
I also need to be able to specify default values for keyword arguments.
If an argument was specified in the call, it will behave one way; if that argument was not specified in the call but was instead taken from the default, it will use the default and will behave a different way.
I do have a working solution, but am wondering if there is a cleaner, safer, more concise way to accomplish the goal:
import json
def addFeature(*args,**kwargs):
defaults={
'p1':1,
'p2':2,
'p3':3
}
mergedKwargs = defaults | kwargs # start with defaults; overwrite with any specified kwargs items
print(f'args:{args}')
print('keyword arguments specified in the call to this function:')
print(json.dumps(kwargs,indent=3))
print('mergedKwargs:')
print(json.dumps(mergedKwargs,indent=3))
# unpack to local variables
(p1,p2,p3)=(mergedKwargs[k] for k in ('p1','p2','p3'))
print(f'local values: p1={p1} p2={p2} p3={p3}')
addFeature(1,2,p1=5)
addFeature(3,4,p2=7,p3=9)
running this code:
PS C:\Users\caver\Documents\GitHub> python argsTest.py
call to addFeature: args: (1, 2)
keyword arguments specified in the call to this function:
{
"p1": 5
}
mergedKwargs:
{
"p1": 5,
"p2": 2,
"p3": 3
}
local values: p1=5 p2=2 p3=3
call to addFeature: args: (3, 4)
keyword arguments specified in the call to this function:
{
"p2": 7,
"p3": 9
}
mergedKwargs:
{
"p1": 1,
"p2": 7,
"p3": 9
}
local values: p1=1 p2=7 p3=9
PS C:\Users\caver\Documents\GitHub>
One drawback of this method is that the function signature (list of possible arguments) is unknown when using *args and **kwargs.
NonelikeaddFeature(..., p1=None,...)and later remeber what variables was different thanNone, and later replaceNonewith default value (p1 = 1). This can be longer, but you may have signature (of couse problem is that this signature will haveNoneas default value)