首页 > 解决方案 > Use of **kwargs in a function as variable?

问题描述

I have a function that plots a map.

def plot(country, year1, year2, month, obs,**kwargs):

And I have a plotly express function to plot a scatter mapbox:

    fig = px.scatter_mapbox(df_to_plot, 
                        lat="LATITUDE",#latitude of the station 
                        lon="LONGITUDE", #longitude of the station
                        hover_name = "NAME", #when hovered, show the name of the station
                        color = "coef", #color differs by coef
                        zoom=zoom, #default zoom size.
                        mapbox_style = mapbox_style, #style of the plot.
                       color_continuous_scale=color_continuous_scale, #scale of the colorbar, red to gray countinuous.

...

Here, I want to pass parameters for zoom, mapbox_style, color_continuous_scale.

However, when I call the function and pass the parameters:

fig =plot("India", 1980, 2020, 1, 
                                   obs = 10,
                                   zoom = 2,
                                   mapbox_style="carto-positron",
                                   color_continuous_scale=color_map)

I get an error: name 'zoom' is not defined.

Maybe I am using the **Kwargs wrong. How do I pass the parameters manually and use them in the function?

标签: pythonkeyword-argument

解决方案


If these are mandatory argument for plot, just accept the arguments by name like all the rest; you can make them keyword-only if you like by putting them after a * (without a name, it makes the rest keyword-only; with a name, it would allow arbitrary additional positional arguments, so probably not a good idea here):

def plot(country, year1, year2, month, obs, *, zoom, mapbox_style, color_continuous_scale):

and the body of plot doesn't change.

If those arguments aren't always needed, and there's a wide variety of arguments you sometimes need in different code paths, you just need to know that **kwargs collects them as a string keyed dict (you can't dynamically allocate space for a variable number of locals, so actually making zoom conditionally defined as a raw name in local scope isn't possible), so look up the extra names the same way you would on a dict, e.g.:

fig = px.scatter_mapbox(df_to_plot, 
                        lat="LATITUDE",#latitude of the station 
                        lon="LONGITUDE", #longitude of the station
                        hover_name="NAME", #when hovered, show the name of the station
                        color="coef", #color differs by coef
                        zoom=kwargs['zoom'], #default zoom size.
                        mapbox_style=kwargs['mapbox_style'], #style of the plot.
                        color_continuous_scale=kwargs['color_continuous_scale'], #scale of the colorbar, red to gray countinuous.

and you'll get a KeyError at lookup time if it turns out the caller failed to provide them.


推荐阅读