Question

I have several layers of function calls, passing around a common dictionary of key word arguments:

def func1(**qwargs):
    func2(**qwargs)
    func3(**qwargs)

I would like to supply some default arguments in some of the subsequent function calls, something like this:

def func1(**qwargs):
    func2(arg = qwargs.get("arg", default), **qwargs)
    func3(**qwargs)

The problem with this approach is that if arg is inside qwargs, a TypeError is raised with "got multiple values for keyword argument".

I don't want to set qwargs["arg"] to default, because then func3 gets this argument without warrant. I could make a copy.copy of the qwargs and set "arg" in the copy, but qwargs could have large data structures in it and I don't want to copy them (maybe copy.copy wouldn't, only copy.deepcopy?).

What's the pythonic thing to do here?

Was it helpful?

Solution

Just build and use another dict for the purpose of calling func2, leaving the original alone for the later call to func3:

def func1(**qwargs):
    d = dict(arg=default)
    d.update(qwqargs)
    func2(**d)
    func3(**qwargs)

This is if you want a setting for arg in qwargs to override the default. Otherwise (if you want default to override any possible setting for arg in qwargs):

def func1(**qwargs):
    d = dict(qwargs, arg=default)
    func2(**d)
    func3(**qwargs)

since the keyword-argument to dict overrides the value in the positional argument, if any.

OTHER TIPS

To create a new dict with the same keys and values you can use

 newdict=dict(qwargs)

If qwargs doesn't contain really many keys that's cheap.

If it's possible you could rewrite the functions to take their args really as dict instead of multiple args.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top