[Python]函数的各种传参
- 2020 年 3 月 10 日
- 筆記
文章目录
- @[toc]
- 0. 环境
- 1. 位置参数
- 2. 默认参数
- 3. 可变参数
- 3.1. 用法
- 3.2. 简洁调用方法
- 4. 关键字参数
- 4.1. 用法
- 4.2. 简洁调用方法
- 4.3. 检查关键字参数
- 5. 命名关键字参数
- 5.1. 用法
- 5.2.. 特殊情况
- 6. 组合参数
- 7. 参考文献
Python函数的各种传参
0. 环境
python3.6
1. 位置参数
没什么好说的,和C++语言
都一样,不过调用起来有点方便,就以幂运算为例吧。
# x是底数,n为幂次 def power(x, n): ret = 1 while n > 0: n = n - 1 ret = ret * x return ret
调用函数的时候,一个萝卜一个坑,按部就班就ok了
>> power(3,2) >> 9
2. 默认参数
# x是底数,n为幂次(默认函数执行平方运算) def power(x, n=2): ret = 1 while n > 0: n = n - 1 ret = ret * x return ret
>> power(3) 9 >>
这也和C++
中定义函数一样,可以在声明中设置默认参数,不过要注意的是:
必须设定参数在前(如函数中的底数
x
),默认参数(如函数中的幂次n
)在后,否则Python
的解释器会报错
这样做的好处是什么?当然是调用起来省事啦,懒惰才是第一生产力!
注意:
设定默认参数时,默认值
必须是一个不变的对象,比如说上述例子中n=2
中的2
。
3. 可变参数
3.1. 用法
编写一个函数sum()
可以计算传入变量的和。
def sum(*numbers): ret = 0 print(type(numbers)) # 测试参数类型 for n in numbers: ret = ret + n return ret
>> print(sum(1, 2, 3, 4, 5)) <class 'tuple'> 15 >> print(sum()) <class 'tuple'> 0 >>
可以看出,在定义函数时,在参数
前面加入一个*
,就可以使得函数内部得到一个tuple
数组。
3.2. 简洁调用方法
如果已经有了一个list
或是tuple
,要传入一个有可变参数的函数,有两种方法。
- 方法1: 把
list
或是tuple
用下标,一个一个传入(麻烦) - 方法2: 在传入参数(
list
或是tuple
)的变量名前加*
(有点类似C语言
指针的用法,自己体会一下吧)
>> ns = [1, 2, 3] # 方法1(麻烦) >> sum(ns[0], ns[1], ns[2]) # 方法2(推荐) >> sum(*ns)
4. 关键字参数
4.1. 用法
- 可变参数 允许你传入
0
个或任意个
参数,这些可变参数在函数调用时自动组装为一个tuple
- 关键字参数 允许你传入
0
个或任意个
含 参数名的参数,这些关键字参数在函数内部自动组装为一个dict
def car(brand, price, **kw): print("brand: ", brand) print("price: ", price) print("kw: ", kw) print("type(kw): ", type(kw))
# 情况1 >> car('Volkswagen', '9999') brand: Volkswagen price: 9999 kw: {} type(kw): <class 'dict'> >> # 情况2 >> car('Volkswagen', '9999', place='Germany', salePlace='China') brand: Volkswagen price: 9999 kw: {'place': 'Germany', 'salePlace': 'China'} type(kw): <class 'dict'> >>
4.2. 简洁调用方法
类似3.2节
,如果已经有了一个字典dict
,可以在调用函数时把它当做关键字参数
传入进入,只需要在前面变量名前加**
>> extraParam = {'place': 'Germany', 'salePlace': 'China'} >> car('Volkswagen', '9999', **extraParam) brand: Volkswagen price: 9999 kw: {'place': 'Germany', 'salePlace': 'China'} type(kw): <class 'dict'> >>
4.3. 检查关键字参数
其实就是检查字典dict
def car(brand, price, **kw): print("brand: ", brand) print("price: ", price) print("kw: ", kw) print("type(kw): ", type(kw)) # 检查代码 if 'place' in kw: # 有place这个参数 pass if 'salePlace' in kw: # 有salePlace这个参数 pass
5. 命名关键字参数
5.1. 用法
如果要 限制 关键字参数 的 名字
,就可以用 命名关键字参数,例如,只接收place
和salePlace
作为 关键字参数。这种方式定义的函数如下所示:
def car2(brand, price, *, place, salePlace): print("brand: ", brand) print("price: ", price) print("place: ", place) print("salePlace: ", salePlace) print("type(place): ", type(place)) print("type(salePlace): ", type(salePlace))
和关键字参数**kw
不同,命名关键字参数需要一个特殊分隔符*
,*
后面的参数被视为命名关键字参数。
运行情况:
# 情况1 >> car2('Volkswagen', '9999', place='Germany', salePlace='China') brand: Volkswagen price: 9999 place: Germany salePlace: China type(place): <class 'str'> type(salePlace): <class 'str'> # 情况2 >> car2('Volkswagen', '9999', 'Germany', 'China') Traceback (most recent call last): car2('Volkswagen', '9999', 'Germany', 'China') TypeError: car2() takes 2 positional arguments but 4 were given # 情况3 >> car2('Volkswagen', '9999', salePlace='China') Traceback (most recent call last): car2('Volkswagen', '9999', salePlace='China') TypeError: car2() missing 1 required keyword-only argument: 'place' # 情况4 >> car2('Volkswagen', '9999', place='Germany', salePlace='China', city = 'beijing') Traceback (most recent call last): car2('Volkswagen', '9999', place='Germany', salePlace='China', city = 'beijing') TypeError: car2() got an unexpected keyword argument 'city'
解释:
- 情况1: 一般调用方式;
- 情况2: 因为调用时缺少参数名
place
和salePlace
,Python解释器把这4
个参数均视为位置参数
,但car2()函数
仅接受2
个位置参数
; - 情况3: 由于没有设置默认值,所以命名关键字参数不可以省略;
- 情况4: 没有定义
city
这个命名关键字参数。
注意: 命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错,如情况2所示。
针对情况3出现的问题,只需要设置好参数的默认值就可以避免了:
def car2(brand, price, *, place='', salePlace=''): print("brand: ", brand) print("price: ", price) print("place: ", place) print("salePlace: ", salePlace) print("type(place): ", type(place)) print("type(salePlace): ", type(salePlace))
# 情况1 >> car2('Volkswagen', '9999') brand: Volkswagen price: 9999 place: salePlace: type(place): <class 'str'> type(salePlace): <class 'str'> # 情况2 >> car2('Volkswagen', '9999', salePlace='China') brand: Volkswagen price: 9999 place: salePlace: China type(place): <class 'str'> type(salePlace): <class 'str'>
5.2… 特殊情况
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*
了:
def car3(brand, price, *args, place='', salePlace=''): print("brand: ", brand) print("price: ", price) print("args: ", args) print("place: ", place) print("salePlace: ", salePlace) print("type(args): ", type(args)) print("type(place): ", type(place)) print("type(salePlace): ", type(salePlace))
运行情况:
# 将place参数省略,使用默认参数 >> car3('Volkswagen', '9999', 1, 2, 3, salePlace='China') brand: Volkswagen price: 9999 args: (1, 2, 3) place: salePlace: China type(args): <class 'tuple'> type(place): <class 'str'> type(salePlace): <class 'str'>
注意:
使用命名关键字参数时,如果没有可变参数,就必须加一个*
作为特殊分隔符。如果缺少*
,Python解释器将其视为位置参数
6. 组合参数
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。 注意: 参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数、关键字参数。
我的建议是:别乱搞,函数接口理解性变差,损人不利己。
7. 参考文献
廖雪峰Python教程:https://www.liaoxuefeng.com/wiki/1016959663602400/1017261630425888
OK! 以上,Enjoy~