Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python将不同的**KWARG传递给多个函数_Python_Function_Keyword Argument - Fatal编程技术网

python将不同的**KWARG传递给多个函数

python将不同的**KWARG传递给多个函数,python,function,keyword-argument,Python,Function,Keyword Argument,通过python文档和stackoverflow,我了解了如何在def函数中使用**kwargs。但是,我有一个案例需要两组**KWARG用于两个子功能。有人能告诉我如何正确地分开**kwargs吗 我的目标是:绘制一组点和插值平滑曲线, 还有我的简单示例代码: def smoothy(x,y, kind='cubic', order = 3, **kwargs_for_scatter, **kwargs_for_plot): yn_cor = interp1d(x, y, kind=k

通过python文档和stackoverflow,我了解了如何在def函数中使用**kwargs。但是,我有一个案例需要两组**KWARG用于两个子功能。有人能告诉我如何正确地分开**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

谢谢你的帮助。

没有这样的机制。有一个建议,即Python3.5和下面的泛化参数解包。Python3.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
然后将这些选项作为字典(而不是kwargs)传递到
smoothy

smoothy(x, y, 'cubic', 3, {...}, {...})
因为变量名可能会向调用者公开,所以您可能希望将它们重命名为较短的名称(可能是
scatter\u options
plot\u options

更新:Python 3.5和3.6现在是主流,它们确实支持基于PEP-448的扩展解包语法

>>> d = {'name': 'joe'}
>>> e = {'age': 20}
>>> { **d, **e }
{'name': 'joe', 'age': 20}
然而,在这个用于多个目的地场景的kwargs中,这并没有多大帮助。即使
smoothy()
函数使用统一的kwargs抓包,您也需要确定它们中的哪些用于哪些子函数。最好是一团糟。多个
dict
参数,其中一个要传递给每个kwarg-taking子函数,这仍然是最好的方法。

使用类获得帮助 我来问这个问题,因为我需要做类似的事情。经过一番思考,似乎课堂教学法会对我有所帮助。我希望这也能推广到其他一些国家

import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import interp1d

class KWAs:
    def __init__(self, algo):
        self.algo = algo
        self.kwargs_dict = {
            'scatter_params':{},
            'plot_params':{}
        } # preloading group keys allows plotting when a kwarg group is absent.

    def add_kwargs_to_dict(self, group_name, **kwargs):
        self.kwargs_dict[group_name] = kwargs

    def list_kwargs(self):
        print('Listing all kwarg groups:')
        for kwargs in self.kwargs_dict:
            print('\tkwarg group {}: {}'.format(kwargs, self.kwargs_dict[kwargs]))
        print()

    def get_kwarg_group(self,group):
        print('kwarg group {}: {}'.format(group, self.kwargs_dict[group]))
        print()

    def smoothy(self, x,y, kind='cubic', order = 3):
        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, **self.kwargs_dict['scatter_params'])
        plt.plot(xn, yn_cor(xn), **self.kwargs_dict['plot_params'])

        plt.show()

kwas = KWAs('LSQ')
N = 20
colors = np.random.rand(N)
area = (20 * np.random.rand(N))**2

kwas.add_kwargs_to_dict('scatter_params', s=area, c=colors, alpha=0.5)
kwas.add_kwargs_to_dict('plot_params', linewidth=2.0, color='r')
kwas.list_kwargs()
kwas.get_kwarg_group('scatter_params')
kwas.get_kwarg_group('plot_params')

x = []; y = []
for i in range(N):
    x.append(float(i)*np.pi/float(N))
    y.append(np.sin(x[-1]))

kwas.smoothy(x, y)
我不知道您试图用kwargs控制哪些参数,所以我根据matplotlib示例制作了一些。上述方法有效,您可以将无限数量的kwarg组添加到类的kwargs字典中,并添加可以根据需要使用kwargs的其他方法

下面是使用我添加的参数的输出:

另一种更不同的方法 我意识到我参加聚会有点晚了。然而,在处理由其他几个类组成的类时,我偶然发现了一个类似的问题。我希望避免为每个子类(或-函数)传递字典,如果复制组件类的所有参数并在稍后阶段更新所有参数,那将是非常不安全的

我的解决方案当然不是最短的,也不是很好,但我认为它有一定的优雅。我修改了下面的函数
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
解释

首先,使用
inspect.signature()
列出第一个函数(scatter)接受的参数(
scatter\u args
)。然后从kwargs构造一个新的字典(
scatter\u dict
),只提取参数列表中的项目。在这里使用
dict(kwargs)
可以确保我们循环使用kwargs的副本,这样我们就可以在不出错的情况下更改原始文件。然后可以将这个新字典传递给函数(scatter),并为下一个函数重复这些步骤

一个陷阱是kwargs中的参数名称可能不会重复,因为它现在是一个单独的dict。因此,对于不控制参数名称的预构建函数,此方法可能会遇到问题


这确实允许我将所述合成类用作父类(或子类)(传递kwargs的剩余部分)。

只传递
scatter
plot
作为正常
dict
s?看起来它们是必需的参数。。。然后在函数中使用
**散布
**绘图
。。。你没有对他们做任何其他事情,因为我建议不要再在参数中保留
kwargs\u for
。。。(无论如何,@JonClements看起来我们有一个种族条件/同时编辑,但得出了相同的结论!别担心。。。非常好的答案(尽管我有偏见的咳嗽)。。。我只是不确定是这么简单,还是需要更复杂的东西+我写了一篇关于拼写和选项的文章:)