372

函数参数中的星号有什么作用?

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

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 上。

4

6 回答 6

334

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

有关更多详细信息,请参阅此答案Python 3 文档

于 2013-01-13T08:50:58.730 回答
98

虽然原始答案完全回答了这个问题,但只是添加了一些相关信息。单个星号的行为源自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):
        ...

用简单的英语来说,这意味着要传递 key 的值,您需要将其显式传递为key="value".

于 2016-09-02T04:16:24.207 回答
49
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'}
于 2018-10-22T19:20:12.010 回答
32

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

>>> 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 开发人员选择让您以前一种方式编写它。

于 2019-11-25T04:12:31.110 回答
23

假设你有功能:

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

您可以通过 2 种方式调用此函数:

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

假设您希望sum仅使用关键字参数调用函数。

您添加*到函数参数列表以标记位置参数的结尾。

所以函数定义为:

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

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

于 2019-11-01T13:14:20.333 回答
-2

我发现以下链接对解释非常有帮助**args并且**kwargs

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

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

下面先定义演示函数,有两个例子,一个with *args,一个with**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)
于 2019-05-05T10:07:59.900 回答