参数列表中的裸星号起什么作用?什么是“仅关键字”参数?

2024-11-28 08:37:00
admin
原创
7
摘要:问题描述:函数参数中的裸星号有什么作用?当我查看pickle 模块时,我看到了这一点:pickle.dump(obj, file, protocol=None, *, fix_imports=True) 我知道参数前面有一个星号和两个星号(用于可变数量的参数),但这个前面什么都没有。我很确定这与 pickle...

问题描述:

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

当我查看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)

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   649  
  搭建自己的时间服务器不仅是一项技术挑战,更是一种提升工作效率和数据管理能力的有效手段。通过搭建时间服务器,企业可以确保所有设备和系统的时间同步,减少因时间不同步而导致的错误和混乱。此外,时间服务器还能增强网络安全性,确保日志和事件记录的时间戳准确无误,这对于故障排查和安全审计至关重要。选择合适的时间服务器软件在搭建时间...
服务器软件   0  
  问题描述:我有这个代码:import sys def random(size=16): return open(r"C:Users avishankarvDocumentsPythonkey.txt").read(size) def main(): key = random(13...
  0  
  问题描述:在pandas库中很多时候都有选项可以就地更改对象,例如使用以下语句...df.dropna(axis='index', how='all', inplace=True) 我很好奇返回了什么以及对象在inplace=True传递时和传递时是如何处理的inplace=False。所有操作都是self在何时修改的...
  1  
  问题描述:一个看似简单、容易的陈述却在我面前显示出一些错误。我有一个名为strings.json的 JSON 文件,如下所示:"strings": [{"-name": "city", "#text": "City"},...
  2  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用