想象一下,我有一个看起来像这样的函数:
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...]
但是,现在我需要每三个人都有一个kwarg。因此,在我看来,列表“看起来”就像这样:
newBigList = [[1,2,3],[4,5,6],word='hello',[1,3,5],[2,4,6],word='world',etc...]
因此,有两个问题要做到这一点。
1)我可以构建一个包含kwarg字符串的列表,而不将函数作为实际参数读入吗? word
中的newBigList
(s)可以是字符串吗?
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)
但是,现在我需要这些关键字。如果需要,我非常乐意提供更多信息。感谢
答案 0 :(得分:3)
简短回答:不。
更长的答案:取决于你想要做什么。 Python界面不能接受你想要的签名,那么函数是什么,你实际上想要做什么?
答案 1 :(得分:3)
功能签名并不像您认为的那样工作。 matplotlib's plot
函数的关键字参数适用于您指定的所有行:
如果使用一个绘图命令创建多行,则kwargs将应用于所有这些行,例如:
plot(x1, y1, x2, y2, antialised=False)
如果要为每一行指定单独的颜色,则需要将它们转换为可以作为每三个位置参数传递的格式字符串。也许您可以将它们格式化为HTML样式十六进制代码:#RRGGBB
或者,或者每行拨打plot
一次,并将color
元组作为关键字参数传递一次。
答案 2 :(得分:3)
有几个原因阻止你做你想做的事情:
color=something, ..., color=other
会引发异常x1, y1, color=something, x2
是错误的。即使按预期方式工作,仍有matplotlib
文档说明:
如果使用一个plot命令创建多行,则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 first 扩展了*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只会引发错误并避免这种歧义。