python pass different **kwargs to multiple functions

user3287545 picture user3287545 · Oct 23, 2014 · Viewed 8.5k times · Source

From python doc and stackoverflow, I understand how to use the **kwargs in my def function. However, I have a case need two sets of **kwargs for two sub functions. Can someone show me how to separate the **kwargs properly?

Here is my goal: to plot set of points and interpolated smooth curve,
and my naive sample code:

def smoothy(x,y, kind='cubic', order = 3, **kwargs_for_scatter, **kwargs_for_plot):
    yn_cor = interp1d(x, y, kind=kind, assume_sorted = False)
    xn = np.linspace(np.min(x), np.max(x), len(x) * order)
    plt.scatter(x,y, **kwargs_for_scatter)
    plt.plot(xn, yn_cor(xn), **kwargs_for_plot);
    return

Thanks for help.

Answer

Jonathan Eunice picture Jonathan Eunice · Oct 23, 2014

There is no such mechanism. There is a proposal, PEP-448, whereby Python 3.5 and following generalize argument unpacking. Python 3.4 and previous don't support it. Best you can do in general:

def smoothy(x,y, kind='cubic', order = 3, kwargs_for_scatter={}, kwargs_for_plot={}):
    yn_cor = interp1d(x, y, kind=kind, assume_sorted = False)
    xn = np.linspace(np.min(x), np.max(x), len(x) * order)
    plt.scatter(x,y, **kwargs_for_scatter)
    plt.plot(xn, yn_cor(xn), **kwargs_for_plot);
    return

Then pass in those options as dictionaries, not kwargs, to smoothy.

smoothy(x, y, 'cubic', 3, {...}, {...})

Because the variable names would then be possibly exposed to callers, you may want to rename them something shorter (perhaps scatter_options and plot_options).

Update: Python 3.5 and 3.6 are now mainstream, and they indeed support an extended unpacking syntax based on PEP-448.

>>> d = {'name': 'joe'}
>>> e = {'age': 20}
>>> { **d, **e }
{'name': 'joe', 'age': 20}

This does not, however, help much in this kwargs-intended-for-multiple-destinations scenario. Even if the smoothy() function took a unified grab-bag of kwargs, you'd need to determine which of them were intended for which subfunctions. Messy at the very best. Multiple dict parameters, one intended to be passed to each kwarg-taking subfunction, still the best approach.