2

想象一下,我有一个看起来像这样的函数:

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(s) 可以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)

但是,现在我需要这些关键字。如果需要,我非常乐意提供更多信息。谢谢

4

3 回答 3

3

函数签名不像你想象的那样工作。matplotlib 函数的plot关键字参数适用于您指定的所有行:

如果您使用一个绘图命令制作多行,则 kwargs 适用于所有这些行,例如:

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

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

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

于 2013-11-12T22:38:05.817 回答
3

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

  • 您只能在函数调用中指定一次关键字,因此color=something, ..., color=other引发异常
  • 你不能混合关键字参数和位置,所以x1, y1, color=something, x2是一个错误。
  • 即使这按您的预期工作,仍然有matplotlibs 文档指出:

    如果您使用一个绘图命令制作多行,则 kwargs 适用于所有这些行

    即你不能color=只用于其中一条线,或者每条线一次。这是一个“全局”属性。如果要为每条线指定不同的颜色,则必须使用其他提供线颜色的方法。


我相信,根据您的问题,您不清楚位置参数和关键字参数是如何工作的,因此我将尝试在这方面为您提供线索。

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

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

该功能具有:

  • 两个参数pos_kw1pos_kw2可以通过位置参数或关键字参数分配
  • 只能用位置参数指定*args的参数
  • 只能用关键字参数指定kw_only的参数

注意:默认值与关键字参数无关。他们只是使参数不需要。

要了解参数传递的机制,您可以认为(尽管严格来说并不正确)如果 python 执行函数调用(例如):

a_function(1, 2, *'abc', kw_only=7)

它首先将所有位置参数收集到一个元组中。在上面的情况下,结果元组是pos_args = (1, 2, 'a', 'b', 'c'),然后将所有关键字参数收集到 adict中,在这种情况下kw_args = {'kw_only': 7},之后,它调用函数做:

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参数或多或少的工作方式)。

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

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

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

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

于 2013-11-12T22:38:50.757 回答
3

简短的回答:没有。

更长的答案:取决于您要做什么。Python 接口无法接受你想要的签名,那么函数是什么,你到底想做什么?

于 2013-11-12T22:12:57.810 回答