Python五类参数:
- 位置参数
- 关键字参数
- 默认参数
- 可变位置参数
- 可变关键字参数
五类参数
定义函数f,只有一个参数a,a既可能为位置参数,也可能为关键字参数,这取决于调用函数f的传参。
1 | def f(a): |
位置参数
如下调用函数f,a就是位置参数,英文positional argument,并且a被赋值为1:
1 | f(1) |
关键字参数
下面调用函数f,a就是关键字参数,英文keyword argument,a同样被赋值为1:
1 | f(a=1) |
默认参数
函数f如下,有一个默认值0,那么,a就是默认参数,且默认值为0
1 | def f(a=0): |
对于以上函数,就有两种不同的调用方式:
1.按照a的默认值调用
1 | f() |
2.默认参数a值为1
1 | f(1) |
可变位置参数和可变关键字参数
f函数定义如下:
1 | def f(a, *b, **c): |
函数f的参数稍显复杂,但也是最常用的函数参数定义结构。
- 出现一个星号的参数b,这是可变位置参数;
- 带两个星号的参数c,这是可变关键字参数。
可变表示函数被赋值的变量个数是变化的。
如下调用函数f:
1 | f(1,2,3,w=4,h=5) |
参数b被传递2个值,参数c也被传递2个值。可变位置参数b被解析为元组,可变关键字参数c被解析为字典。
接下来在调用函数f:
1 | f(1,2,w=4) |
参数b被传递1个值,参数c被传递1个值。
所以,称带星号的变量为可变的。
查看参数
借助Python的inspect模块查看参数的类型。
首先,导入inspect模块
1
from inspect import signature
函数f定义,如下:
1
2
3def f(a, *b):
print(f'a:{a}, b:{b}')
...
查看参数类型
1
2
3
4
5for name, val in signature(f).parameters.items():
print(name,val.kind)
...
a POSITIONAL_OR_KEYWORD
b VAR_POSITIONAL
看到,参数a既可能是位置参数,也可能是关键字参数。参数b为可变位置参数。
函数f定义如下:
1 | def f(*, a, **b): |
查看参数类型
1 | for name, val in signature(f).parameters.items(): |
看到参数a只可能为KEYWORD_ONLY关键字参数。因为参数a前面有个星号,星号后面的参数a只可能是关键字参数,而不可能是位置参数。
如下,不能这样调用函数f:
1 | f(1, b=2, c=3) |
传递规则
Python强大多变,原因之一在于函数参数的多样化。下面,介绍Python中五类参数的传递赋值规则。
要求开发者遵守更多的约束规则。如果不了解这些规则,函数调用时,可能会出现各种各样的调用异常。
常见的有以下六类:
| 序号 | 异常说明 | 描述 |
|---|---|---|
| 1 | SyntaxError: positional argument follows keyword argument | 位置参数位于关键字参数后面 |
| 2 | TypeError: f() missing 1 required keyword-only argument: ‘b’ | 必须传递的关键字参数缺失 |
| 3 | SyntaxError: keyword argument repeated | 关键字参数重复 |
| 4 | TypeError: f() missing 1 required positional argument: ‘b’ | 必须传递的位置参数缺失 |
| 5 | TypeError: f() got an unexpected keyword argument ‘a’ | 没有这个关键字参数 |
| 6 | TypeError: f() takes 0 positional arguments but 1 was given | 不需要位置参数但却传递 1 个 |
下面总结,6个主要的参数使用规则:
规则1:不带默认的位置参数缺一不可
函数调用时,根据函数定义的参数位置来传递参数,是最常见的参数类型。
1 | def f(a): |
如下带有两个参数,传值时必须两个都赋值。
1 | def f(a, b): |
规则2:关键字参数必须在位置参数右边
在调用f时,通过键—值方式为函数形参传值。
1 | def f(a): |
参数a变为关键字参数。
但是,下面调用,就会出现:位置参数位于关键字参数后面的异常。
1 | def f(a, b): |
如下调用是可以的
1 | f(20, b=1) |
规则3:对同一个形参不能重复传值
下面方式调用也是会报异常
1 | def f(a, **b): |
规则4:默认参数的定义应该在位置形参右面
在定义函数时,可以为形参提供默认值。
对于有默认值的形参,调用函数时,如果为该参数传值,则使用传入的值,否则使用默认值。
如下b是默认参数
1 | def f(a, b=1): |
默认参数通过应该定义成不可变类型。
规则5:可变位置参数不能传入关键字参数
如下定义的参数a为可变位置参数:
1 | def f(*a): |
调用方法:
1 | f(1) |
但是,不能这么调用:
1 | f(a=1) |
规则6:可变关键字参数不能传入位置参数
如下,a是可变关键字参数:
1 | def f(**a): |
调用方法
1 | f(a=1) |
但是,不能这么调用:
1 | f(1) |