use*_*545 21 python function kwargs
从python doc和stackoverflow,我理解如何在我的def函数中使用**kwargs.但是,我有一个案例需要两套**kwargs用于两个子功能.有人能告诉我如何正确地分离**kwargs吗?
这是我的目标:绘制点集和插值平滑曲线,
以及我天真的示例代码:
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
Run Code Online (Sandbox Code Playgroud)
感谢帮助.
小智 14
我意识到我参加聚会有点晚了。但是,在处理由其他几个类组成的类时,我偶然发现了一个类似的问题。我想避免为每个子类(或函数)传递字典,并且复制组件类的所有参数是非常反干的,另外还要冒在稍后阶段必须更新所有参数的风险。
我的解决方案当然不是最短的,也不是很好,但我认为它有一定的优雅。我修改了smoothy下面的函数:
import inspect
def smoothy(x,y, kind='cubic', order = 3, **kwargs):
yn_cor = interp1d(x, y, kind=kind, assume_sorted = False)
xn = np.linspace(np.min(x), np.max(x), len(x) * order)
scatter_args = [k for k, v in inspect.signature(plt.scatter).parameters.items()]
scatter_dict = {k: kwargs.pop(k) for k in dict(kwargs) if k in scatter_args}
plt.scatter(x,y, **scatter_dict)
plot_args = [k for k, v in inspect.signature(plt.plot).parameters.items()]
plot_dict = {k: kwargs.pop(k) for k in dict(kwargs) if k in plot_args}
plt.plot(xn, yn_cor(xn), **plot_dict);
return
Run Code Online (Sandbox Code Playgroud)
解释
要开始了,做一个列表(scatter_args的参数)的第一个函数(散)接受,使用inspect.signature()。然后scatter_dict从 kwargs构建一个新的字典 ( ),只提取也在我们的参数列表中的项目。dict(kwargs)在此处使用可确保我们循环遍历 kwargs 的副本,以便我们可以更改原始版本而不会出错。然后可以将这个新字典传递给函数 (scatter),并为下一个函数重复这些步骤。
一个陷阱是 kwargs 中的参数名称可能不会重复,因为它现在是单个 dict。因此,对于不控制参数名称的预构建函数,您可能会遇到此方法的问题。
这确实允许我将所述组合类用作父类(或子类)(传递 kwargs 的其余部分)。
Jon*_*ice 11
没有这样的机制.有一个提议,PEP-448,其中Python 3.5和以下泛化参数解包.Python 3.4和之前的版本不支持它.一般来说你可以做的最好:
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
Run Code Online (Sandbox Code Playgroud)
然后将这些选项作为词典而不是kwargs传递给smoothy.
smoothy(x, y, 'cubic', 3, {...}, {...})
Run Code Online (Sandbox Code Playgroud)
因为变量名称可能会暴露给调用者,所以您可能希望将它们重命名为更短的(可能scatter_options和plot_options).
更新:Python 3.5和3.6现在是主流,它们确实支持基于PEP-448的扩展解包语法.
>>> d = {'name': 'joe'}
>>> e = {'age': 20}
>>> { **d, **e }
{'name': 'joe', 'age': 20}
Run Code Online (Sandbox Code Playgroud)
然而,这对于这个用于多目的地的kwargs场景并没有多大帮助.即使该smoothy()函数采用统一的kwargs抓包,您也需要确定哪些是针对哪些子函数.凌乱的最好.多个dict参数,一个旨在传递给每个获取kwarg的子功能,仍然是最好的方法.