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

2024-11-28 08:37:00
admin
原创
9
摘要:问题描述:函数参数中的裸星号有什么作用?当我查看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  
  如何借鉴华为IPD体系优化企业研发?在当今竞争激烈的市场环境中,企业要想保持技术领先和产品竞争力,必须拥有一套高效且严谨的研发管理体系。华为作为全球领先的ICT解决方案提供商,其集成产品开发(IPD, Integrated Product Development)体系与质量管理体系(如ISO 9000系列)的融合实践,...
IPD项目管理   0  
  IPD流程图的7种经典绘制方法详解在产品开发领域,集成产品开发(Integrated Product Development,简称IPD)流程被广泛应用,以提高产品开发的效率和质量。IPD流程图作为这一流程的可视化工具,其绘制方法至关重要。本文将详细介绍七种经典的IPD流程图绘制方法,帮助项目管理人员和团队更好地理解和...
IPD研发管理体系   0  
  IPD流程:企业创新管理的核心引擎在当今快速变化的市场环境中,企业要想持续保持竞争力,就必须不断进行创新。而IPD(Integrated Product Development,集成产品开发)流程作为一种先进的产品开发管理模式,正逐渐成为众多企业提升创新能力、加速产品上市速度、降低开发成本的重要选择。本文将深入探讨IP...
IPD管理   0  
  IPD流程与传统产品开发流程的概述在产品开发领域,企业不断寻求高效、系统的管理方法以确保产品能够顺利从概念转化为市场成功的产品。集成产品开发(Integrated Product Development,简称IPD)流程与传统产品开发流程是两种截然不同的管理理念和方法。传统产品开发流程往往以职能部门为核心,各部门按顺序...
IPD流程中PDCP是什么意思   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用