函数参数中的星号?

在函数的参数中使用一个星号有什么作用?

当我查看pickle模块时,我看到了这个:

pickle.dump(obj, file, protocol=None, *, fix_imports=True)

我知道在参数之前有一个单星号和双星号(用于可变数量的参数),但这之前什么都没有。我很确定这和腌黄瓜没有关系。这可能只是一个例子。当我把这个发给翻译时,我才知道它的名字:

>>> def func(*):
...     pass
...
File "<stdin>", line 1
SyntaxError: named arguments must follow bare *

如果重要的话,我用的是python 3.3.0。

77608 次浏览

*用于强制调用者使用命名参数——因此,当没有下列关键字参数时,不能将*定义为参数的函数。

更多细节请参见这个答案Python 3文档

而原来的答案完全回答了问题,只是增加了一些相关信息。单个星号的行为源自PEP-3102。引用相关章节:

The second syntactical change is to allow the argument name to
be omitted for a varargs argument. The meaning of this is to
allow for keyword-only arguments for functions that would not
otherwise take a varargs argument:


def compare(a, b, *, key=None):
...

在简单的英语中,这意味着要传递for key的值,你需要显式地将它作为key="value"传递。

def func(*, a, b):
print(a)
print(b)


func("gg") # TypeError: func() takes 0 positional arguments but 1 was given
func(a="gg") # TypeError: func() missing 1 required keyword-only argument: 'b'
func(a="aa", b="bb", c="cc") # TypeError: func() got an unexpected keyword argument 'c'
func(a="aa", b="bb", "cc") # SyntaxError: positional argument follows keyword argument
func(a="aa", b="bb") # aa, bb

上面的例子使用**kwargs

def func(*, a, b, **kwargs):
print(a)
print(b)
print(kwargs)


func(a="aa",b="bb", c="cc") # aa, bb, {'c': 'cc'}

我发现下面的链接非常有助于解释**args**kwargs:

https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/

基本上,除了上面的答案之外,我还从上面的网站(来源:https://pythontips.com/author/yasoob008/)中学到了以下内容:

下面首先定义了演示函数,有两个示例,一个使用*args,另一个使用**kwargs

def test_args_kwargs(arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3


# first with *args
>>> args = ("two", 3,5)
>>> test_args_kwargs(*args)
arg1: two
arg2: 3
arg3: 5


# now with **kwargs:
>>> kwargs = {"arg3": 3, "arg2": "two","arg1":5}
>>> test_args_kwargs(**kwargs)
arg1: 5
arg2: two
arg3: 3

因此,*args允许你动态地构建一个参数列表,这些参数将按照它们被提供的顺序被获取,而**kwargs可以启用NAMED参数的传递,并可以根据NAME进行相应的处理(与它们被提供的顺序无关)。

该网站继续指出,正确的参数顺序应该是:

some_func(fargs,*args,**kwargs)

假设你有一个函数:

def sum(a,key=5):
return a + key

你可以用两种方式调用这个函数:

sum(1,2)sum(1,key=2)

假设你想要函数sum只使用关键字参数被调用。

*添加到函数形参列表中,以标记位置参数的结束。

函数定义为:

def sum(a,*,key=5):
return a + key

只能使用sum(1,key=2)

从语义上讲,这意味着它后面的参数仅限关键字,因此如果您试图提供参数而不指定其名称,则会得到一个错误。例如:

>>> def f(a, *, b):
...     return a + b
...
>>> f(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 1 positional argument but 2 were given
>>> f(1, b=2)
3

实际上,这意味着您必须使用关键字参数调用函数。如果没有实参名称的提示,就很难理解实参的目的,通常会这样做。

例如,比较sorted(nums, reverse=True)和如果你写sorted(nums, True)。后者的可读性要差得多,因此Python开发人员选择让您以前者的方式编写。