Python 函数参数中的空星号?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14301967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bare asterisk in function arguments?
提问by Eric
What does a bare asterisk in the arguments of a function do?
函数参数中的星号有什么作用?
When I looked at the pickle module, I see this:
当我查看pickle 模块时,我看到了:
pickle.dump(obj, file, protocol=None, *, fix_imports=True)
I know about a single and double asterisks preceding arguments (for variable number of arguments), but this precedes nothing. And I'm pretty sure this has nothing to do with pickle. That's probably just an example of this happening. I only learned its name when I sent this to the interpreter:
我知道参数前面有一个单星号和双星号(对于可变数量的参数),但这并不在前面。而且我很确定这与泡菜无关。这可能只是发生这种情况的一个例子。当我把这个发给口译员时,我才知道它的名字:
>>> def func(*):
... pass
...
File "<stdin>", line 1
SyntaxError: named arguments must follow bare *
If it matters, I'm on python 3.3.0.
如果重要的话,我使用的是 python 3.3.0。
采纳答案by Kimvais
Bare *is used to force the caller to use named arguments - so you cannot define a function with *as an argument when you have no following keyword arguments.
Bare*用于强制调用者使用命名参数 - 因此*当您没有以下关键字参数时,您无法将函数定义为参数。
See this answeror Python 3 documentationfor more details.
有关更多详细信息,请参阅此答案或Python 3 文档。
回答by u1860929
While the original answer answers the question completely, just adding a bit of related information. The behaviour for the single asterisk derives from PEP-3102. Quoting the related section:
虽然原答案完全回答了问题,只是添加了一些相关信息。单个星号的行为源自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):
...
In simple english, it means that to pass the value for key, you will need to explicitly pass it as key="value".
在简单的英语中,这意味着要传递 key 的值,您需要将其显式传递为key="value".
回答by laycat
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
the above example with **kwargs
上面带有 **kwargs 的例子
def func(*, a, b, **kwargs):
print(a)
print(b)
print(kwargs)
func(a="aa",b="bb", c="cc") # aa, bb, {'c': 'cc'}
回答by lb_so
I've found the following link to be very helpful explaining *, *argsand **kwargs:
我发现以下链接对解释非常有帮助*,*args并且**kwargs:
https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/
https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/
Essentially, in addition to the answers above, I've learned from the site above (credit: https://pythontips.com/author/yasoob008/) the following:
基本上,除了上面的答案之外,我还从上面的网站(来源:https: //pythontips.com/author/yasoob008/)了解到以下内容:
With the demonstration function defined first below, there are two examples, one with *argsand one with **kwargs
用下面先定义的演示函数,有两个例子,一个有*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
So *argsallows you to dynamically build a list of arguments that will be taken in the order in which they are fed, whereas **kwargscan enable the passing of NAMED arguments, and can be processed by NAME accordingly (irrespective of the order in which they are fed).
So*args允许您动态构建一个参数列表,这些参数将按照它们被提供的顺序被采用,而**kwargs可以启用 NAMED 参数的传递,并且可以由 NAME 相应地处理(不管它们被提供的顺序) .
The site continues, noting that the correct ordering of arguments should be:
该站点继续,并指出参数的正确顺序应该是:
some_func(fargs,*args,**kwargs)
回答by rok
Suppose you have function:
假设你有函数:
def sum(a,key=5):
return a + key
You can call this function in 2 ways:
您可以通过两种方式调用此函数:
sum(1,2)or sum(1,key=2)
sum(1,2)或者 sum(1,key=2)
Suppose you want function sumto be called only using keyword arguments.
假设您希望sum仅使用关键字参数调用函数。
You add *to the function parameter list to mark the end of positional arguments.
您添加*到函数参数列表以标记位置参数的结尾。
So function defined as:
所以函数定义为:
def sum(a,*,key=5):
return a + key
may be called only using sum(1,key=2)
只能使用 sum(1,key=2)
回答by kaya3
Semantically, it means the arguments following it are keyword-only, so you will get an error if you try to provide an argument without specifying its name. For example:
从语义上讲,这意味着它后面的参数只有关键字,所以如果你试图提供一个参数而不指定它的名字,你会得到一个错误。例如:
>>> 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
Pragmatically, it means you have to call the function with a keyword argument. It's usually done when it would be hard to understand the purpose of the argument without the hint given by the argument's name.
实际上,这意味着您必须使用关键字参数调用该函数。如果没有参数名称给出的提示,很难理解参数的目的,通常会这样做。
Compare e.g. sorted(nums, reverse=True)vs. if you wrote sorted(nums, True). The latter would be much less readable, so the Python developers chose to make you to write it the former way.
比较例如sorted(nums, reverse=True)与如果你写的sorted(nums, True)。后者的可读性要差得多,因此 Python 开发人员选择让您以前者的方式编写它。

