4.8.3.Python特殊参数

【原文】

4.8.3. Special parameters

By default, arguments may be passed to a Python function either by position or explicitly by keyword. For readability and performance, it makes sense to restrict the way arguments can be passed so that a developer need only look at the function definition to determine if items are passed by position, by position or keyword, or by keyword.

A function definition may look like:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
      -----------    ----------     ----------
        |             |                  |
        |        Positional or keyword   |
        |                                - Keyword only
         -- Positional only

where / and * are optional. If used, these symbols indicate the kind of parameter by how the arguments may be passed to the function: positional-only, positional-or-keyword, and keyword-only. Keyword parameters are also referred to as named parameters.

4.8.3.1. Positional-or-Keyword Arguments

If / and * are not present in the function definition, arguments may be passed to a function by position or by keyword.

4.8.3.2. Positional-Only Parameters

Looking at this in a bit more detail, it is possible to mark certain parameters as positional-only. If positional-only, the parameters’ order matters, and the parameters cannot be passed by keyword. Positional-only parameters are placed before a / (forward-slash). The / is used to logically separate the positional-only parameters from the rest of the parameters. If there is no / in the function definition, there are no positional-only parameters.

Parameters following the / may be positional-or-keyword or keyword-only.

4.8.3.3. Keyword-Only Arguments

To mark parameters as keyword-only, indicating the parameters must be passed by keyword argument, place an * in the arguments list just before the first keyword-only parameter.

4.8.3.4. Function Examples

Consider the following example function definitions paying close attention to the markers / and *:

>>>

>>> def standard_arg(arg):
...     print(arg)
...
>>> def pos_only_arg(arg, /):
...     print(arg)
...
>>> def kwd_only_arg(*, arg):
...     print(arg)
...
>>> def combined_example(pos_only, /, standard, *, kwd_only):
...     print(pos_only, standard, kwd_only)

The first function definition, standard_arg, the most familiar form, places no restrictions on the calling convention and arguments may be passed by position or keyword:

>>>

>>> standard_arg(2)
2

>>> standard_arg(arg=2)
2

The second function pos_only_arg is restricted to only use positional parameters as there is a / in the function definition:

>>>

>>> pos_only_arg(1)
1

>>> pos_only_arg(arg=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: 'arg'

The third function kwd_only_args only allows keyword arguments as indicated by a * in the function definition:

>>>

>>> kwd_only_arg(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given

>>> kwd_only_arg(arg=3)
3

And the last uses all three calling conventions in the same function definition:

>>>

>>> combined_example(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: combined_example() takes 2 positional arguments but 3 were given

>>> combined_example(1, 2, kwd_only=3)
1 2 3

>>> combined_example(1, standard=2, kwd_only=3)
1 2 3

>>> combined_example(pos_only=1, standard=2, kwd_only=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: combined_example() got some positional-only arguments passed as keyword arguments: 'pos_only'

Finally, consider this function definition which has a potential collision between the positional argument name and **kwds which has name as a key:

def foo(name, **kwds):
    return 'name' in kwds

There is no possible call that will make it return True as the keyword 'name' will always bind to the first parameter. For example:

>>>

>>> foo(1, **{'name': 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() got multiple values for argument 'name'
>>>

But using / (positional only arguments), it is possible since it allows name as a positional argument and 'name' as a key in the keyword arguments:

>>>

>>> def foo(name, /, **kwds):
...     return 'name' in kwds
...
>>> foo(1, **{'name': 2})
True

In other words, the names of positional-only parameters can be used in **kwds without ambiguity.

4.8.3.5. Recap

The use case will determine which parameters to use in the function definition:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):

As guidance:

  • Use positional-only if you want the name of the parameters to not be available to the user. This is useful when parameter names have no real meaning, if you want to enforce the order of the arguments when the function is called or if you need to take some positional parameters and arbitrary keywords.

  • Use keyword-only when names have meaning and the function definition is more understandable by being explicit with names or you want to prevent users relying on the position of the argument being passed.

  • For an API, use positional-only to prevent breaking API changes if the parameter’s name is modified in the future.

【译】

4.8.3.特殊参数

默认情况下,可以通过位置,或者用定义的关键字把参数传递给Python函数。为了代码的可读性和高效,设置了相应参数传递的制约方式。这样,开发者需要查看函数定义,确定函数迭代时,是否应当通过位置,位置或关键字,关键字传递相应的参数。

剖析一个函数定义:

 

在定义函数时,/和*是可选项。这两个标识符决定了函数以什么方式传递参数,仅限位置,位置或关键字,仅限关键字。关键字参数被引用的时候必须和参数定义时的名字一致。

4.8.3.1位置或关键字参数

如果定义函数时没有/和*,可以用位置或关键字把参数传递给函数。

4.8.3.2仅限位置参数

看定义函数代码段中的一点,就可以确定仅限位置参数。如果是仅限位置参数,这个参数的顺序很重要,并且这个参数不能通过关键字传递。仅限位置参数在一个/(正斜杠)的前面。/从逻辑上把仅限位置参数和其他参数区分开。在函数定义中没有/,就没有仅限位置参数。

/后的参数可能是位置或关键字参数,也有可能是关键字参数。

4.8.3.3.仅限关键字参数

被设定为仅限关键字参数,表明这个参数必须通过参数的关键字传递。在参数列表中*只出现在第一个仅限关键字参数前面。

4.8.3.4.函数实例

研究下面的函数定义实例,重点关注标识符/和*:

第一个被定义的函数standard_arg,是最常见的形式,没有限定位置,可以用位置或关键字激活函数,传递参数。

第二个函数pos_only_arg在函数定义时用了/,被限定只能通过位置传递参数。

第三个函数kwd_only_args在函数定义时,用了一个*,表明只允许使用关键字参数。

最后一个函数定义时,覆盖了三种方式的参数。

最后,研究函数定义时位置参数name和关键字参数**kwds的名字很关键,它们的命名会导致潜在的冲突和混淆。

关键字“name”总是被绑定给第一个参数,可变关键字参数的关键字和位置或关键字参数的名字一样,返回逻辑值“True”激活函数是不可能的。

但是用/(仅限位置参数),不但允许name作为位置参数的名称,而且’name’还可以作为可变关键字参数的关键字。

换句话说,仅限位置参数的名字可以在可变关键字参数**kwds里使用而不会引起歧义。

拓展实例:

4.8.3.5.重述要点

实际应用决定在函数定义中使用哪些参数。

指南:

如果你不想让用户使用参数名称;当函数被激活时你只需要强调参数的顺序;或者你需要获取一些参数的位置和任意关键字,就需要限定位置。这种应用下参数名字没有实际意义。

当名字有意义,并且通过使用明确的名称使函数定义更容易理解,或者你希望防止用户依赖位置传递参数,就使用限定关键字。

对于一个API,如果参数的名字在将来是会改变的,使用仅限位置以防止破坏API更改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值