参数列表中的裸星号起什么作用?什么是“仅关键字”参数?
- 2024-11-28 08:37:00
- admin 原创
- 9
问题描述:
函数参数中的裸星号有什么作用?
当我查看pickle 模块时,我看到了这一点:
pickle.dump(obj, file, protocol=None, *, fix_imports=True)
我知道参数前面有一个星号和两个星号(用于可变数量的参数),但这个前面什么都没有。我很确定这与 pickle 无关。这可能只是这种情况的一个例子。我把它发送给解释器后才知道它的名字:
>>> def func(*):
... pass
...
File "<stdin>", line 1
SyntaxError: named arguments must follow bare *
如果这很重要的话,我使用的是 python 3.3.0。
解决方案 1:
Bare*
用于强制调用者使用命名参数 - 因此*
当您没有以下关键字参数时,您无法定义一个以作为参数的函数。
有关更多详细信息,请参阅此答案或Python 3 文档。
解决方案 2:
虽然原始答案完全回答了问题,但只是添加了一些相关信息。单个星号的行为源自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="value"
。
解决方案 3:
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'}
解决方案 4:
从语义上讲,这意味着跟在它后面的参数是关键字专用的,因此如果您尝试提供参数而不指定其名称,则会收到错误。例如:
>>> 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
从实用角度来说,这意味着你必须使用关键字参数来调用函数。这通常是在难以理解参数目的(如果没有参数名称的提示)的情况下进行的。
比较一下 egsorted(nums, reverse=True)
和 如果你写的sorted(nums, True)
。 后者的可读性会差很多,所以 Python 开发人员选择让你用前一种方式来编写。
强制参数为关键字参数(或位置参数,用 表示/
)的另一个具体原因是确保 的使用一致@lru_cache
。修饰符(例如)@lru_cache
看不到这一点f(1, 2)
,并f(1, b=2)
提供相同的参数,因此如果两个调用都在同一个程序中进行,您将无法充分利用缓存的优势。例如:
>>> from functools import lru_cache
>>> @lru_cache
... def f(a, b):
... print(f'Non-cached call with {a=}, {b=}')
... return a + b
...
>>> f(1, 2)
Non-cached call with a=1, b=2
3
>>> f(1, 2) # cached result is used
3
>>> f(1, b=2) # cached result is not used
Non-cached call with a=1, b=2
3
因此,强制所有调用以相同的方式传递参数具有实际的好处。
解决方案 5:
假设您有以下功能:
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)
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件