是否可以交替使用*args和**kwargs?

2024-05-13 10:31:07 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个函数,看起来像这样:

myFunction(arg, arg, kwarg, arg, arg, kwarg, etc...):

其中arg是*arg,kwarg是*kwarg。在此之前,我的函数看起来像myFunction(*args):,我只使用了一长串的*参数,我只需要传入一个像这样的大列表

^{pr2}$

大列表看起来像=[[1,2,3],[4,5,6],'hello',[1,3,5],[2,4,6],'world',etc...]

但是,现在我需要每三次辩论一次。所以,在我看来,现在的清单“看起来”是这样的:

newBigList = [[1,2,3],[4,5,6],word='hello',[1,3,5],[2,4,6],word='world',etc...]

所以,有两个问题可以让这项工作成功。在

1)我可以用kwarg的字符串构造一个列表而不让函数将其作为实际参数读入吗?newBigList中的word是字符串吗?在

2)您可以交替使用kwargs和args吗?我知道夸格斯语通常是用字典来完成的。有没有可能交替使用这两种方法?在

一如既往,如果有人知道更好的方法,我很乐意改变我的方式。在

编辑方法如下。它是一个matplotlib方法,用于绘制多边形(或一组多边形):

plot([x1], [y1], color=(RBG tuple), [x2], [y2], color=(RGB tuple), etc...)

其中[x1]是第一个多边形的x值列表,[y1]是第一个多边形的y值列表,依此类推。在

问题是,要使用RBG值作为color参数,我需要包含color关键字。为了使问题更加复杂,我使用random.random()模块生成一个随机元组。在

所以,我有一个所有多边形的x值列表,所有多边形的y值列表,以及随机RBG颜色的元组列表。它们看起来像这样:

x = [[1,2,3], [4,5,6], [7,8,9]]
y = [[0,9,8], [7,6,5], [4,3,2]]
colors = [(.45, .645, .875), (.456, .651, .194), (.813, .712, .989)]

所以,有三个多边形要绘制。在我能做关键字之前,我所做的就是zip它们都放在一个元组中,然后像这样使用它。在

list_of_tuples = zip(x, y, colors)
denormalized = [x for tup in list_of_tuples for x in tup]
plot.plot(*denormalized)

但是,现在我需要这些关键词。如果需要的话,我很乐意提供更多的信息。谢谢


Tags: 方法函数列表参数plotargetcargs
3条回答

有几个原因阻止你去做你想做的事情:

  • 在函数调用中,只能指定一个关键字一次,因此color=something, ..., color=other会引发异常
  • 不能混合关键字参数和位置,因此x1, y1, color=something, x2是一个错误。在
  • 即使这如您所料,仍然有matplotlib的文档说明:

    If you make multiple lines with one plot command, the kwargs apply to all those lines

    也就是说,不能只对其中一行使用color=,也不能对每行使用一次。这是一个“全球性”的财产。如果要为每一行指定不同的颜色,则必须使用其他提供线条颜色的方法。


我相信,通过你的问题,你还不清楚位置和关键字参数是如何工作的,所以我会在这方面给你一个线索。在

首先,有不同种类的参数。我将介绍一个例子来解释这些区别:

def a_function(pos_kw1, pos_kw2, *args, kw_only)

此功能具有:

  • 两个参数pos_kw1pos_kw2,可由位置参数或关键字参数指定
  • 一个参数*args,只能用位置参数指定
  • 一个参数kw_only,它只能用关键字参数指定

注意:默认值与关键字参数无关。它们只是使参数不再是必需的。在

要理解参数传递的机制,您可以认为(虽然严格来说这不是真的),如果python执行函数调用(例如):

^{pr2}$

它首先将所有位置参数收集到一个元组中。在上面的情况下,结果元组将是pos_args = (1, 2, 'a', 'b', 'c'),然后将所有关键字参数收集到dict中,在本例中是{},然后调用函数执行以下操作:

a_function(*pos_args, **kw_args)

注意:由于dicts没有顺序,所以关键字的顺序无关紧要。在

在你的问题中,你想做的是:

plot(x, y, color=X, x2, y2, color=Y, ...)

由于调用实际使用*pos_args**kw_args函数:

  • 不知道color=X是在y之后指定的。在
  • 不知道color=Y是在y2之后指定的。在
  • 不知道color=X是在color=Y之前指定的。在

推论:不能多次指定同一个参数,因为python无法知道应该将哪个出现项指定给哪个参数。另外,在定义函数时,您不能使用两个同名的参数。 (不,python不会自动构建值列表或类似列表。它只会引发一个错误。)

您还可以认为python首先在不考虑关键字参数的情况下扩展*pos_args,然后再展开**kw_args。如果您认为这样可以清楚地理解函数调用,例如:

# naive intent: assign pos_kw1 via keyword and pos_kw2 via positional
# assuming python will skip positional that were already provided as keyword args

a_function(1, pos_kw1=2)

# or even:
a_function(pos_kw1=2, 1)   # hoping order matters

没有任何意义,因为1是通过位置参数分配给pos_kw1的,当扩展关键字参数时,它将被重新分配。在

另一种解释是,在调用a_function(*pos_args, **kw_args)中,*pos_args是一个简单的元组解包操作,相当于:

pos_kw1, pos_kw2, *args = pos_args

(在python2中,您不能使用*,但是*args参数或多或少就是这样工作的)。在

元组解包不会跳过元素:它只是简单地分配给元组的连续元素,函数调用也是如此:有一个no检查位置参数是否已经通过关键字传递,最终被跳过。他们被简单地、盲目地分配。在

由于这些限制,允许在关键字参数后面出现位置的函数调用没有任何意义,因此不能执行以下操作:

plot(x, y, color=X, x2, ...)

允许这样的函数调用只会欺骗人们,让他们认为关键字或t的顺序很重要在解包时可以跳过hat参数,因此Python只会引发一个错误并避免这种歧义。在

函数签名的工作方式不像你想象的那样。matplotlib's ^{}函数的关键字参数应用于指定的所有行:

If you make multiple lines with one plot command, the kwargs apply to all those lines, e.g.:

plot(x1, y1, x2, y2, antialised=False)

如果要为每一行指定单独的颜色,则需要将它们转换为格式字符串,然后作为第三个位置参数传递。也许您可以将它们格式化为HTML样式的十六进制代码:#RRGGBB

或者,每行调用plot一次,并将color元组作为关键字参数传递一次。在

简而言之:不

长话短说:这取决于你到底想做什么。Python接口不能接受您想要的签名,那么这个函数是什么,您实际要做什么?在

相关问题 更多 >