是否可以交替使用* args和** kwargs?
想象一下,我有一个看起来像这样的函数:
myFunction(arg, arg, kwarg, arg, arg, kwarg, etc...):
arg是* arg,kwarg是* kwarg。 在此之前,我的函数看起来像myFunction(*args):
并且我只使用了一个很长的* args列表,并且我会传入一个像这样的大列表
myFunction(*bigList):
bigList看起来像= [[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构造一个没有函数读入它的实际参数的列表吗? 可以在word
的(一个或多个) newBigList
是字符串?
2)你可以替换kwargs和args吗? 我知道kwargs通常是用字典完成的。 是否可以交替使用两者?
与往常一样,如果有人知道这样做的更好方法,我会很乐意改变我的方式。
编辑这里的方法。 它是一个绘制多边形(或一堆多边形)的matplotlib方法:
plot([x1], [y1], color=(RBG tuple), [x2], [y2], color=(RGB tuple), etc...)
其中[x1]
是第一个多边形的x值列表, [y1]
是第一个多边形的y值列表,依此类推。
问题是,要使用颜色参数的RBG值,我需要包含颜色关键字。 更复杂的是,我使用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)
但是,现在我需要这些关键字。 如果需要,我非常乐意提供更多信息。 谢谢
函数签名不会按照您认为的方式工作。 matplotlib的plot
函数的关键字参数适用于您指定的所有行:
如果您使用一个绘图命令制作多行,则kwargs适用于所有这些行,例如:
plot(x1, y1, x2, y2, antialised=False)
如果要为每行指定单独的颜色,则需要将它们转换为格式字符串,您可以将其作为每三个位置参数进行传递。 也许你可以把它们格式化为HTML风格的十六进制代码: #RRGGBB
或者,每行调用一次plot
,并将一次color
元组作为关键字参数传递一次。
简短的回答:不。
较长的答案:取决于你正在尝试做什么。 Python接口不能接受你想要的签名,那么函数是什么,你究竟在做什么?
有几个原因妨碍你做你正在做的事情:
color=something, ..., color=other
会引发异常 x1, y1, color=something, x2
是一个错误。 即使这个按照你的预期工作,仍然有matplotlib
的文档说明:
如果您使用一个绘图命令制作多行,则kwargs适用于所有这些行
也就是说,你不能只使用一种color=
或每行一次。 这是一个“全球”财产。 如果要为每行指定不同的颜色,则必须使用其他提供线条颜色的方法。
我相信,在你的问题中,你不清楚位置和关键字的论点是如何工作的,所以我会试着在这方面给你一个线索。
首先,有不同类型的参数。 我将介绍一个例子来解释不同之处:
def a_function(pos_kw1, pos_kw2, *args, kw_only)
这个功能有:
pos_kw1
, pos_kw2
可以由位置参数或关键字参数分配 *args
只能用位置参数指定 kw_only
注意:默认值与关键字参数无关 。 他们只是使参数不需要。
为了理解参数传递的机制,你可以认为(虽然它不是严格的)如果python执行一个函数调用(例如):
a_function(1, 2, *'abc', kw_only=7)
它首先将所有位置参数收集到一个元组中。 在上面的情况下,所得到的元组将会是pos_args = (1, 2, 'a', 'b', 'c')
,然后将所有关键字参数收集到一个dict
,在这种情况下kw_args = {'kw_only': 7}
,之后,它会调用这个函数:
a_function(*pos_args, **kw_args)
注意:由于dict
没有排序,关键字的顺序无关紧要。
在你的问题中,你想要做一些事情:
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
参数或多或少的作用)。
元组解开不会跳过元素:它只是分配给元组的连续元素,函数调用也是这样:没有检查位置参数是否已经通过关键字传递并最终被跳过。 他们只是盲目分配。
由于这些限制,允许在关键字参数后出现定位符的函数调用没有任何意义,因此您无法执行类似以下操作:
plot(x, y, color=X, x2, ...)
允许这样的函数调用只会欺骗人们让他们认为命令对关键字来说很重要,或者在解包时跳过这些参数等等,所以Python只会引发错误并避免这种模糊性。
链接地址: http://www.djcxy.com/p/18179.html上一篇: Is it possible to alternate the use of *args and **kwargs?