Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Splitting kwargs between function calls

From time to time I face this dilemma. Suppose I have a function like this:

def foo(..., **kwargs):
    ...
    actor = make_actor(..., **a_kwargs)
    return actor.act(..., **b_kwargs)

I want to let the caller specify kwargs to pass to make_actor() (a_kwargs), and to act() (b_kwargs). The problem is, of course, that foo can only take **kwargs once.

(In almost all cases a_kwargs and b_kwargs share no common keys, so we don't need to worry about param-name clashes).

I can think of several approaches, each with its own clear disadvantages/limitations.

def foo1(..., **kwargs):
    ...
    a_kwargs = {k:kwargs.pop(k) for k in kwargs.keys() if k in ['arg1','arg2',...]}
    actor = make_actor(..., **a_kwargs)
    return actor.act(..., **kwargs)

def foo2(..., arg1=DEFAULT1, arg2=DEFAULT2, ..., **b_kwargs):
    ...
    actor = make_actor(..., arg1=arg1, arg2=arg2, ...)
    return actor.act(..., **b_kwargs)

def foo3(..., a_kwargs={}, **b_kwargs):
    ...
    actor = make_actor(..., **a_kwargs)
    return actor.act(..., **b_kwargs)

def foo4(..., a_kwargs={}, b_kwargs={}):
    ...
    actor = make_actor(..., **a_kwargs)
    return actor.act(..., **b_kwargs)

Which is the most pythonic? Is there another approach I overlooked which is superior to the four above?

In the general case we might want to split kwargs for passing to more than two other functions.

like image 292
shx2 Avatar asked Dec 09 '15 17:12

shx2


1 Answers

In general, the fourth option makes the most sense.

Even though it compromises on the ability to use kwargs in your main function, it makes the code clear, allows for future changes and reduces excessive listing of arguments. It also doesn't mean you have both an excessive list of kwargs and a dictionary going into the same function, which seems inconsistent.

Simple is better than complex, Readability counts, practicality beats purity

like image 171
Annonymous Avatar answered Oct 03 '22 07:10

Annonymous