python-3.x 函数参数中是否有星号?

voj3qocg  于 2023-01-03  发布在  Python
关注(0)|答案(6)|浏览(152)

函数参数中的星号有什么作用?
当我查看pickle模块时,我看到了以下内容:

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

我知道在parameters前面有一个或两个星号(用于参数数量可变的情况),但是这个星号前面什么都没有,而且我很确定这和pickle没有关系,这可能只是一个例子,我只是在把它发送给解释器的时候才知道它的名字:

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

如果有关系的话,我用的是python 3.3.0。

wbrvyc0a

wbrvyc0a1#

*用于强制调用方使用命名参数-因此,如果没有以下关键字参数,则不能将*作为参数来定义函数。
更多细节请参见this answer或Python 3文档。

t3irkdon

t3irkdon2#

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

fcg9iug3

fcg9iug33#

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'}
zxlwwiss

zxlwwiss4#

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

>>> 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开发人员选择让你用前一种方式来写。

aor9mmx1

aor9mmx15#

假设你有函数:

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)调用

qojgxg4l

qojgxg4l6#

我发现下面的链接非常有助于解释**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)

相关问题