解锁 Python 函数形参新玩法:仅位置、仅关键字及综合定义攻略
Python 中,函数参数默认可按位置或显式关键字传递。但为提升代码可读性与效率,限制参数传递方式很有必要。开发者查看函数定义,便可明确参数是仅按位置、按位置或关键字,还是仅按关键字传递。
这对 API 函数定义尤为关键,使用仅限位置形参能防止未来修改形参名引发的 API 破坏性变动,可有效保障 API 稳定性与兼容性。
下面为你详细介绍如何在函数定义中使用这些参数类型。
python函数定义:
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2): ----------- ---------- ---------- | | | | Positional or keyword | | - Keyword only -- Positional only
/
和 *
是可选的。这些符号表明形参如何把参数值传递给函数:位置、位置或关键字、关键字。关键字形参也叫作命名形参。
按位置或关键字形参(Positional-or-Keyword Parameters)
这是 Python 中最常见的参数类型,参数既可以通过位置传递,也可以通过关键字传递。
def multiply_numbers(a, b):
return a * b
# 按位置传递
result1 = multiply_numbers(3, 5)
print(result1) # 输出: 15
# 按关键字传递
result2 = multiply_numbers(a=3, b=5)
print(result2) # 输出: 15
仅按位置形参(Positional-only Parameters)
从 Python 3.8 开始,我们可以使用斜杠 /
来指定仅按位置传递的参数。在斜杠之前的参数只能通过位置传递,不能使用关键字传递。
def add_numbers(a, b, /):
return a + b
# 正确的调用方式
result = add_numbers(3, 5)
print(result) # 输出: 8
# 错误的调用方式,会抛出 TypeError
# result = add_numbers(a=3, b=5)
仅按关键字形参(Keyword-only Parameters)
使用星号 *
可以指定后面的参数为仅按关键字传递的参数。在星号之后的参数必须使用关键字传递,不能通过位置传递。
def divide_numbers(a, b, *, precision=2):
result = a / b
return round(result, precision)
# 正确的调用方式
result = divide_numbers(10, 3, precision=3)
print(result) # 输出: 3.333
# 错误的调用方式,会抛出 TypeError
# result = divide_numbers(10, 3, 3)
python函数形参综合定义
除了上面的3种方式外,我们还可以将上面3中方式综合在一个函数里面,既我们能够把仅按位置形参、按位置或关键字形参以及仅按关键字形参这三种形参定义方式综合在一个函数之中。 一下为示例
def comprehensive_function(a, b, /, c, d, *, e, f):
"""
此函数综合了仅按位置、按位置或关键字、仅按关键字三种形参定义方式。
:param a: 仅按位置传递的参数
:param b: 仅按位置传递的参数
:param c: 按位置或关键字传递的参数
:param d: 按位置或关键字传递的参数
:param e: 仅按关键字传递的参数
:param f: 仅按关键字传递的参数
:return: 所有参数的和
"""
return a + b + c + d + e + f
# 正确的调用方式
result = comprehensive_function(1, 2, 3, d=4, e=5, f=6)
print(result) # 输出: 21
# 错误的调用方式
# result = comprehensive_function(a=1, b=2, 3, 4, e=5, f=6)
# 这里 a 和 b 是仅按位置形参,不能使用关键字传递,会抛出 TypeError
代码解释
a
和 b
是仅按位置形参,因为它们位于 /
之前,所以在调用函数时只能通过位置来传递,不能使用关键字。c
和 d
是按位置或关键字形参,它们处于 /
和 *
之间,既可以通过位置传递,也能使用关键字传递。e
和 f
是仅按关键字形参,由于它们在 *
之后,因此在调用函数时必须使用关键字来传递。通过这种综合使用不同形参定义方式的方法,能够让函数的参数传递更加灵活和明确,从而提升代码的可读性与可维护性。
总结
/
分隔,在 /
之前的参数只能按位置传递。*
分隔,在 *
之后的参数只能按关键字传递。通过合理使用这些参数类型,可以让函数定义更加清晰,提高代码的可读性和可维护性,特别是在 API 函数的定义中,可以避免因形参名修改而导致的兼容性问题。
作者:tekin