如果
dirs
参数只指定了一个参数(位置或关键字)用于
foo
,例如一个字符串或一个字符串列表,换句话说,如果你想像这样调用
foo
:
foo("folder_name", other args)
或者
foo(["folder_name1", "folder_name2, ...], other args)
如果不需要在名称前加上
*
,那么你就不需要在函数参数中添加星号。而你答案中提到的“解决方法”实际上是正确的方法。请参见:
https://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions。
但是,如果
dirs
指定了任意序列的参数,并且你想要能够执行以下操作:
foo(other args, "folder_name1", "folder_name2",...)
如您所描述的,Python 2和Python 3存在差异。如您所见,在Python 3中存在仅限关键字参数,相比之下Python 2则不存在。具体信息请参见https://docs.python.org/3/glossary.html#term-parameter和https://docs.python.org/2/glossary.html#term-parameter。
在函数定义的参数列表前包含一个单一的var-positional参数或裸*,可以定义关键字参数。
因此,使用Python 3定义foo时不会出现问题。
def foo(*dirs, arg2, arg3=None, arg4=None, arg5=False, arg6=False):
并像这样调用:
foo('folder_name', arg2=100, arg3=['string', 'string2'], arg4='test6', arg5=True, arg6=False)
注意,在调用中,你正确地在
"folder_name"
之后提供了所有参数(甚至是
arg2
)作为关键字参数,因此在Python3中起作用。
但在Python2中,没有关键字-only参数。所以,正如你提到的,你既不能有
* parameter之后的常规参数
,也不能有
关键字参数之后的非关键字参数
。这就是为什么即使你将
*dirs
留在参数列表的最后,你也不能使用前面的参数作为关键字参数来调用
foo
。不过,你可以仍然将
*dirs
留在参数列表的最后,并且在调用
foo
时将之前的参数作为位置参数提供。例如(python 2.7):
def bar(a=1, b=2, *c):
return (a, b, c)
bar(1, 2, 3)
bar(1, b=3, 3)
bar(1, 2)
bar(1)
因此,正如您所见,即使它允许您使用默认值为a、b定义bar(请参见上面链接中的位置或关键字),但它们不会被使用,即a和b是位置(必需的)。
最后,还要检查Python2文档中的这些链接:https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists 和 https://docs.python.org/2/faq/programming.html#what-is-the-difference-between-arguments-and-parameters
def foo(arg2, *dirs, arg3=None, arg4=None, arg5=False, arg6=False,):
这个函数定义中的参数是什么意思呢?arg2
是一个必需的参数,后面跟着零个或多个位置参数*dirs
。arg3
和arg4
是可选的命名参数,默认值为None
。而arg5
和arg6
是布尔类型的可选参数,默认值分别为False
。 - Jean-François Fabreregular parameter after * parameter
的错误信息。 - saysarg2
添加默认值,然后arg2
必须用作关键字参数(无论如何都要这样做),但顺序没问题。另外,FYI,对Python2.7的支持已于一周前停止。 - h4z3*dirs
的末尾处调用foo
时,仍然会出现SyntaxError: non-keyword arg after keyword arg
。 我是这样进行调用的:foo(arg2 = 15,arg3 = ['hello there'],arg4 ='test',arg5 = True,arg6 = False, 'folder_name')
。 不确定为什么仍然会出现错误。 - says