*(单星号)和/(斜杠)在作为独立参数时有什么作用?

22 浏览
0 Comments

*(单星号)和/(斜杠)在作为独立参数时有什么作用?

这个问题已经有答案了:

函数参数中的光秃秃的星号是什么意思?

help()中列出方法签名时斜杠的含义是什么?

在以下函数定义中,*/代表什么意思?

def func(self, param1, param2, /, param3, *, param4, param5):
     print(param1, param2, param3, param4, param5)

注意:不要与*args|**kwargs中的单个|双个星号混淆(已解决)

admin 更改状态以发布 2023年5月23日
0
0 Comments

文档中所述,斜杆用于指定参数只能采用位置方式传入,文档中解释如下:

有一个新的函数参数语法/,用于表明某些函数参数必须以位置方式指定,并且不能用作关键字参数。对于使用 Larry Hastings 的Argument Clinic 工具注释的 C 函数,help() 中显示的注释形式是相同的。

而对于星号,文档中在此处提到:docs

对于默认参数,对应的参数可以在调用时省略,此时将使用该参数的默认值进行替换。如果一个参数有默认值,那么其后的所有参数直到“*”也必须有默认值 - 这是语法上的限制,在语法中并未表达。


def func(self, param1, param2, /, param3, *, param4, param5):
     print(param1, param2, param3, param4, param5)

因此,可以进行以下调用:

obj.func(10, 20, 30, param4=50, param5=60)

以及:

obj.func(10, 20, param3=30, param4=50, param5=60)

0
0 Comments

有一个新的函数参数语法/用来指明一些函数参数必须按位置指定,不能作为关键字参数使用。[这是Python 3.8中新增的]

文档说明了位置参数的一些使用案例/好处。

  1. 它可以使纯Python函数完全模拟现有的C编码函数的行为。例如,内置的pow()函数不接受关键字参数:

    def pow(x, y, z=None, /):
        "Emulate the built in pow() function"
        r = x ** y
        return r if z is None else r%z
    

  2. 另一个用例是在参数名不有帮助的情况下排除关键字参数。例如,内置的len()函数具有签名len(obj, /)。这排除了尴尬的调用,例如:

    len(obj='hello')  # The "obj" keyword argument impairs readability
    

  3. 将参数标记为位置参数的另一个好处是,它允许在将来更改参数名称而不会破坏客户端代码。例如,在统计模块中,参数名称可能会在将来更改。这是通过以下函数规范实现的:

    def quantiles(dist, /, *, n=4, method='exclusive')
        ...
    

*用于强制调用者使用具有名称的参数。 Django文档包含了一个显然解释了命名参数的用例的部分

表单字段不再接受可选的参数作为位置参数

为了防止由于表单字段参数顺序不正确而导致的运行时错误,内置表单字段的可选参数不再被接受为位置参数。例如:

forms.IntegerField(25, 10)

会触发异常,应替换为:

forms.IntegerField(max_value=25, min_value=10)

假设我们有一个叫做func的方法,

def func(self, param1, param2, /, param3, *, param4, param5):
     print(param1, param2, param3, param4, param5)

它必须被调用为

obj.func(10, 20, 30, param4=50, param5=60)

或者

obj.func(10, 20, param3=30, param4=50, param5=60)

即,

  1. param1param2必须按位置指定。
  2. param3可以使用位置或关键字参数调用。
  3. param4param5必须使用关键字参数调用。

演示:

>>> class MyClass(object):
...     def func(self, param1, param2, /, param3, *, param4, param5):
...         return param1, param2, param3, param4, param5
...
>>> obj = MyClass()
>>>
>>> assert obj.func(10, 20, 30, param4=40, param5=50), obj.func(
...     10, 20, param3=30, param4=40, param5=50
... )

0