在python中函数传参可以使用位置传参和关键字传参组合。
现定义一个函数,计算两个数相除的结果,但是,会有两个参数判断,如果除数为0,是抛出ZeroDivisionError,还是返回无穷(infinity),如果结果溢出,是抛出OverflowError,还是返回0。
如下:
def safe_division(number, divisor,
ignore_overflow,
ignore_zero_division):
try:
return number / divisor
except OverflowError:
if ignore_overflow:
return 0
raise
except ZeroDivisionError:
if ignore_zero_division:
return float('inf')
raise
如果想在结果溢出返回0,可以如下调用:
res = safe_division(1.0, 100**500, True, True)
print(res)
如果想在除数为0返回无穷,如下调用:
res = safe_division(1.0, 0, False, True)
print(res)
但是可以看到函数最后两个参数都是boolean值,调用者很容易弄错位置。如果我们想调用者后面两个参数必须按照关键字传参,应该如何做?
在python3,8后,可以声明只能通过关键字指定的参数(key-only argument
)。可以使用*
号把参数分开,左边是位置参数,右边是关键字参数。如下:
def safe_division(number, divisor, *, # 前面是位置参数,后面是关键字参数
ignore_overflow=False,
ignore_zero_division=False):
try:
return number / divisor
except OverflowError:
if ignore_overflow:
return 0
raise
except ZeroDivisionError:
if ignore_zero_division:
return float('inf')
raise
这样如果后面两个还按位置传参,就会出错:
res = safe_division(1.0, 0, False, True)
# TypeError: safe_division() takes 2 positional arguments but 4 were given
当然,这时候后面两个关键字参数还是可以只传一个,另一个用默认值:
res = safe_division(1.0, 0, ignore_zero_division=True)
函数前面两个参数只是两个相除的数,名称意义并不大,如果想让调用者只能按位置传参,还如何做?
python3.8还提供了只能通过位置传参的参数(keywoed-only argument
)。以 /
分割,表示左边只能按位置传参。如下:
def safe_division(number, divisor, /, *,
ignore_overflow=False,
ignore_zero_division=False):
pass
这时候,前面两个参数只能以位置传参,否则报错:
res = safe_division(number=1.0, divisor=0)
# TypeError: safe_division() got some positional-only arguments passed as keyword arguments: 'number, divisor'
如果是在两个符号之间的参数,则既可以用关键字传参,又可以位置传参。这里不在演示。
总结
python3.8之后,函数的参数列表可以使用*
和/
分割,调用时,在*右边的必须使用关键字传参,在 / 左边的必须使用位置传参,两个之间的既可以关键字传参。也可以使用位置传参。
注意*
要写在/
之后。