函数参数中裸星号的目的是什么?

ale*_*cxe 19 python arguments function keyword-argument python-3.x

我已经看到了这个问题(这不是重复的):Python在函数参数中显示星号

在python-3.x中你可以*为函数参数添加一个裸,这意味着(引自docs):

"*"或"*identifier"之后的参数是仅关键字参数,并且只能传递使用的关键字参数.

好的,我已经定义了一个函数:

>>> def f(a, b, *, c=1, d=2, e=3):
...     print('Hello, world!')
... 
Run Code Online (Sandbox Code Playgroud)

我可以通过c,de变量值只能通过指定关键字:

>>> f(1, 2, 10, 20, 30)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 5 were given
>>> f(1, 2, c=10, d=20, e=30)
Hello, world!
Run Code Online (Sandbox Code Playgroud)

问题是:

  • 这种限制/语法糖的动机是什么?
  • 它涵盖了哪些用例?
  • 它真的用在切换到python3的第三方库中吗?

一些"真实世界"的例子会有很大帮助.提前致谢.

Bre*_*arn 16

PEP 3102非常清楚地解释了基本原理:重点是允许函数接受本质上基本上正交的各种"选项".在定义和调用方面,在位置上指定这些都是尴尬的,因为它们没有任何明显的"优先级"可以转化为位置顺序.

在各种库中有很多功能可以从中受益.例如,呼叫签名pandas.read_csv是:

def parser_f(filepath_or_buffer,
                 sep=sep,
                 dialect=None,
                 compression=None,

                 doublequote=True,
                 escapechar=None,
                 quotechar='"',
                 quoting=csv.QUOTE_MINIMAL,
                 skipinitialspace=False,
                 lineterminator=None,

                 header='infer',
                 index_col=None,
                 names=None,
                 prefix=None,
                 skiprows=None,
                 skipfooter=None,
                 skip_footer=0,
                 na_values=None,
                 na_fvalues=None,
                 true_values=None,
                 false_values=None,
                 delimiter=None,
                 converters=None,
                 dtype=None,
                 usecols=None,

                 engine='c',
                 delim_whitespace=False,
                 as_recarray=False,
                 na_filter=True,
                 compact_ints=False,
                 use_unsigned=False,
                 low_memory=_c_parser_defaults['low_memory'],
                 buffer_lines=None,
                 warn_bad_lines=True,
                 error_bad_lines=True,

                 keep_default_na=True,
                 thousands=None,
                 comment=None,
                 decimal=b'.',

                 parse_dates=False,
                 keep_date_col=False,
                 dayfirst=False,
                 date_parser=None,

                 memory_map=False,
                 nrows=None,
                 iterator=False,
                 chunksize=None,

                 verbose=False,
                 encoding=None,
                 squeeze=False,
                 mangle_dupe_cols=True,
                 tupleize_cols=False,
                 infer_datetime_format=False):
Run Code Online (Sandbox Code Playgroud)

除了文件路径之外,其中大多数都是正交选项,用于指定如何解析CSV文件的不同方面.没有特别的理由说明他们会以任何特定顺序通过.你会疯狂地跟踪这些的任何位置顺序.将它们作为关键字传递更有意义.

现在,您可以看到pandas实际上并没有将它们定义为仅限关键字的参数,可能是为了保持与Python 2的兼容性.我想可能许多库因为同样的原因而不使用语法.我不知道哪些库(如果有的话)已经开始使用它.

  • 强制它们成为关键字参数的一个原因是人们不依赖于订单,因此您可以在将来更改它,或者添加新关键字(例如:`ignore_comments ='#'`),逻辑上将在`lineterminator`旁边. (4认同)
  • 哇,这个函数需要太多参数。显然某些东西设计有问题。 (2认同)