簡體   English   中英

python將不同的** kwargs傳遞給多個函數

[英]python pass different **kwargs to multiple functions

通過python doc和stackoverflow,我了解了如何在def函數中使用** kwargs。 但是,我有一個案例需要兩個子函數使用兩組** kwarg。 有人可以告訴我如何正確分離**垃圾嗎?

這是我的目標:繪制點集和插值的平滑曲線,
和我朴素的示例代碼:

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

感謝幫助。

沒有這種機制。 有一個建議書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

然后將這些選項作為字典而不是kwargs傳遞給smoothy

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

因為變量名可能會暴露給調用者,所以您可能希望將它們重命名為更短的名稱(也許是scatter_optionsplot_options )。

更新 :Python 3.5和3.6現在是主流,它們確實支持基於PEP-448的擴展解壓縮語法。

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

但是,在這個kwargs打算用於多個目的地的方案中,這沒有太大幫助。 即使smoothy()函數采用統一的smoothy()包,您也需要確定其中的哪個子函數用於哪些子函數。 最好是凌亂的。 多個dict參數(最好傳遞給每個kwarg子功能)仍然是最好的方法。

另一種更不同的方法

我意識到我參加聚會有點晚了。 但是,在處理由其他幾個類組成的類時,我偶然發現了一個類似的問題。 我想避免為每個子類(或-function)傳遞字典,並且復制組件類的所有參數非常不干 ,而且冒着必須在以后更新所有它們的風險。

我的解決方案當然不是最短的,也不是很好,但是我認為它具有一定的優雅。 我在下面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_args inspect.signature() 然后從kwargs構造一個新的字典( scatter_dict ),僅提取也在我們的參數列表中的項。 在這里使用dict(kwargs)可以確保我們遍歷kwargs的副本,以便我們可以更改原始文件而不會出錯。 然后可以將此新詞典傳遞給函數(散點圖),並為下一個函數重復這些步驟。

一個陷阱是,kwargs中的參數名稱不能重復,因為它現在是一個字典。 因此,對於不控制參數名稱的預構建函數,此方法可能會遇到問題。

這的確使我可以將所述組合類用作父(或子)類(傳遞剩余的kwarg)。

使用課程尋求幫助

我遇到了這個問題,因為我需要做類似的事情。 經過一番思考,似乎課堂教學會對我有所幫助。 我希望這也可以擴展到其他一些人。

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示例中補充了一些參數。 上面的方法行得通,您可以在類的kwargs字典中添加無限數量的kwarg組,並添加可以根據需要使用kwargs的其他方法。

這是使用我添加的參數的輸出: 在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM