*(单星号)和/(斜杠)在作为独立参数时有什么作用?
*(单星号)和/(斜杠)在作为独立参数时有什么作用?
这个问题已经有答案了:
在以下函数定义中,*和/代表什么意思?
def func(self, param1, param2, /, param3, *, param4, param5): print(param1, param2, param3, param4, param5)
注意:不要与*args|**kwargs中的单个|双个星号混淆(已解决)
如文档中所述,斜杆用于指定参数只能采用位置方式传入,文档中解释如下:
有一个新的函数参数语法
/
,用于表明某些函数参数必须以位置方式指定,并且不能用作关键字参数。对于使用 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)
有一个新的函数参数语法/
用来指明一些函数参数必须按位置指定,不能作为关键字参数使用。[这是Python 3.8
中新增的]
文档说明了位置参数的一些使用案例/好处。
它可以使纯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
另一个用例是在参数名不有帮助的情况下排除关键字参数。例如,内置的
len()
函数具有签名len(obj, /)
。这排除了尴尬的调用,例如:len(obj='hello') # The "obj" keyword argument impairs readability
将参数标记为位置参数的另一个好处是,它允许在将来更改参数名称而不会破坏客户端代码。例如,在统计模块中,参数名称可能会在将来更改。这是通过以下函数规范实现的:
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)
即,
param1
、param2
必须按位置指定。param3
可以使用位置或关键字参数调用。param4
和param5
必须使用关键字参数调用。
演示:
>>> 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 ... )