Python编程学习:让函数更加灵活的*args和**kwargs(设计不同数量参数的函数)的简介、使用方法、经典案例之详细攻略
目录
*args和**kwargs(设计不同数量的参数函数)的简介
1、*用法:统计一个班内报名学篮球的同学,但是不知道有多少个人名
2、**用法:统计某个人的爱好,但是不知道这个人有多少种爱好
*args和**kwargs的函数定义使用方法——如何设计不同数量的参数的函数
T1、最基础做法——创建一个list作为参数传入(适合能枚举所有值的情况)
T2、传递可变数量的位置参数的关键用法之*args和**kwargs
1、*args的简介、使用方法(列表/元祖的形式,表示任何多个无名参数)
2、**kwargs的简介、使用方法(字典的形式,表示一个一个有着对应关系的关键字参数)
知识点拓展:函数中参数的顺序——如何接受可变数量的位置参数和命名参数?
1、arg、*args、**kwargs的混合使用简介——args和kwargs组合起来可以传入任意个数的参数,这在参数未知的情况下是很有效的,同时加强了函数的可拓展性。
(3)、同时包含当位置参数、默认参数、*args*、*kwargs参数的情况:正确顺序为位置参数→*args*→默认参数→*kwargs)
2、深入理解解包(unpacking)星号操作符——*和**
(1)、利用解包操作符*应用于list输出内容本身——print()会先将list解包
(3)、利用解包操作符*将list分成三个不同的部分——第一个值、最后一个值和中间的所有值
(4)、利用解包操作符*将两个list列表进行合并—使用*解包可迭代对象(列表和字符串)
(6)、利用解包操作符**解包字典对象——**将两个dict字典进行合并
*args和**kwargs(设计不同数量参数的函数)的简介
*args和**kwargs是 Python编程中可变参数的两种形式,它们两个代表的是变量,表示能够接收可变长度的参数。 需要注意的是
- args和kwargs名称并不重要,它们仅仅是约定俗成的一种命名规则,分别代表“参数”和“关键字参数”,所以,当然可以使用任何其他适当的参数名,比如*ar和**kw;
- *args 必须放在 **kwargs 的前面,因为位置参数在关键字参数的前面。
*args | **kwargs | |
一句话解释 | 将参数打包成tuple给函数体调用。 | 将参数打包关键字参数成dict给函数体调用。 |
功能 | 传递多个参数给函数,设计不同数量的参数的函数,这个参数数目未知,甚至长度可以为0。*args要在**kwags之前,不然会发生语法错误。 args和kwargs组合起来可以传入任意个数的参数,这在参数未知的情况下是很有效的,同时加强了函数的可拓展性。 |
|
顾名思义 | args 是 arguments 的缩写,表示位置参数; | kwargs 是 keyword arguments 的缩写,表示关键字参数。 |
用法 | 当我们不确定要往函数中传入多少个参数,或者想往函数中以列表和元组的形式传参数的情况下,要采用*args; | 当我们不确定要往函数中传入多少个关键词参数,或者想往函数中以字典的值作为关键词参数传参数的情况下,要采用**kwargs。 |
记忆 | args不包含key,即打包成tuple | kwargs包含key,即打包关键字参数 |
-
def a_function(*args, **kwargs):
-
pass
1、*用法:统计一个班内报名学篮球的同学,但是不知道有多少个人名
-
# 1、*用法:统计一个班内报名学篮球的同学,但是不知道有多少个人名
-
def CountLearnBasketballs(*basketNums):
-
print(
"People who study basketball have:" +
", ".join(basketNums))
-
-
-
# (1)、用在函数定义中
-
CountLearnBasketballs(
'马云',
'马化腾',
'李彦宏',
'刘强东',
'王兴',
'丁磊')
-
# (2)、用在函数调用中
-
basketNames = (
'马云',
'马化腾',
'李彦宏',
'刘强东',
'王兴',
'丁磊')
-
CountLearnBasketballs(*basketNames)
-
-
2、**用法:统计某个人的爱好,但是不知道这个人有多少种爱好
-
# 2、**用法:统计某个人的爱好,但是不知道这个人有多少种爱好
-
def CountHobbies(**hobbies):
-
print(
"This person's hobbies include...")
-
for category, fave
in hobbies.items():
-
print(
f"{category}: {fave}")
-
-
CountHobbies(sports=
'basketball', arts=
'drawing', learning=
'reading')
-
*args和**kwargs的函数定义使用方法——如何设计不同数量的参数的函数
T1、最基础做法——创建一个list作为参数传入(适合能枚举所有值的情况)
-
def SUMListsByLists(MoreParasLists):
-
sum_lists =
0
-
for a
in MoreParasLists:
-
sum_lists += a
-
return sum_lists
-
MoreParasLists = [
1,
2,
3,
4,
5,
6]
-
print(SUMListsByLists(MoreParasLists))
-
-
-
-
21
T2、传递可变数量的位置参数的关键用法之*args和**kwargs
1、*args的简介、使用方法(列表/元祖的形式,表示任何多个无名参数)
(1)、*args的简介、使用方法
*args 用来将参数打包成tuple给函数体调用,是非关键字参数,用于元组。此时,不是向函数传递一个list,而是接收位置参数,其原理是传递三个不同的位置参数。
- 上边的SUMListsByArgs会获取所有输入的参数,并将它们打包成一个可迭代的简单对象。
- 该对象可命名为args或者其它名称args123,主要是前缀有“*”号,它是解包(unpacking)操作符。但是,该可迭代对象并非是一个list(可变的),而是一个元组tuple(不可变的)。
-
def args01(*args):
-
print(args, type(args))
-
args01(
'一个处女座的程序猿')
-
-
def args02(x, y, *args):
-
print(x, y, args)
-
args02(
1,
2,
3,
4,
'我是',
'一个处女座的程序猿')
-
-
-
-
-
-
-
-
(
'一个处女座的程序猿',) <
class 'tuple'>
-
1 2 (3, 4, '我是', '一个处女座的程序猿')
(2)、解决上边的问题——如何设计不同数量的参数的函数
-
def SUMListsByArgs(*args):
-
sum_lists =
0
-
# Iterating over the Python args tuple
-
for a
in args:
-
sum_lists += a
-
return sum_lists
-
print(SUMListsByArgs(
1,
2,
3,
4,
5,
6))
-
-
-
-
-
21
2、**kwargs的简介、使用方法(字典的形式,表示一个一个有着对应关系的关键字参数)
(1)、**kwargs的简介、使用方法
**kwargs将参数打包关键字参数以dict形式给函数体调用。其实,**kwargs工作原理和*args有点类似,但不是接收位置参数,而是接收关键字(keyword)参数(也叫被命名的参数)。同样地,该对象可命名为kwargs或者其它名称kwargs123,主要是前缀有“**”号,它是解包(unpacking)操作符。但是该可迭代对象是字典dict,所以获取返回值要使用.values()。
-
def kwargs01(**kwargs):
-
print( kwargs, type(kwargs))
-
kwargs01(a=
'一个处女座的程序猿')
-
-
def kwargs02(**kwargs):
-
print(kwargs)
-
kwargs02(a=
'我是', b=
'一个处女座的程序猿', c=
'!')
-
-
-
-
-
-
-
{
'a':
'一个处女座的程序猿'} <
class 'dict'>
-
{'a':
'我是',
'b':
'一个处女座的程序猿',
'c':
'!'}
(2)、解决上边的问题——如何设计不同数量的参数的函数
-
def StrConnect(**kwargs):
-
strs01=
'';strs02=
''
-
# Iterating over the Python kwargs dictionary
-
for b
in kwargs:
-
strs01 += b
-
for a
in kwargs.values():
-
strs02 += a
-
print(
'keys集合:',strs01)
-
print(
'values集合:',strs02)
-
return strs02
-
print(StrConnect(a=
"大家好", b=
",", c=
"我是", d=
"一个处女座的程序猿", e=
"!"))
-
-
-
-
-
-
keys集合: abcde
-
values集合: 大家好,我是一个处女座的程序猿!
-
大家好,我是一个处女座的程序猿!
知识点拓展:函数中参数的顺序——如何接受可变数量的位置参数和命名参数?
1、arg、*args、**kwargs的混合使用简介——args和kwargs组合起来可以传入任意个数的参数,这在参数未知的情况下是很有效的,同时加强了函数的可拓展性。
args和kwargs组合起来可以传入任意个数的参数,这在参数未知的情况下是很有效的,同时加强了函数的可拓展性。
- 顺序很重要,非默认参数必须在默认参数之前处理,因此*args在**kwargs的前面;
- 参数的正确顺序:位置参数→*args参数→**kwargs参数、非默认参数→默认参数;参数arg、*args、**kwargs三个参数的位置必须是一定的。
-
def VariableParasNum_Test(arg,*args,**kwargs):
-
print(
'VariableParasNum_Test')
-
print(arg,args,kwargs)
-
VariableParasNum_Test(
1,
2,
3,
4,a=
5, b=
6, c=
7)
-
-
-
-
VariableParasNum_Test
-
1 (
2,
3,
4) {
'a':
5,
'b':
6,
'c':
7}
(1)、函数参数中不包含默认参数的情况
其中
- x为1,y为2;
- 3,4都给args,即args=(3,4);
- a=5,b=6,
- y=7以字典形式传给kwargs
-
def VariableParasNum_NoDefault_Test(x, y, *args,**kwargs):
-
print(
'VariableParasNum_NoDefault_Test')
-
print(x, y, args, kwargs)
-
VariableParasNum_NoDefault_Test(
1,
2,
3,
4,a=
5,b=
6,c=
7)
-
-
-
VariableParasNum_NoDefault_Test
-
1
2 (
3,
4) {
'a':
5,
'b':
6,
'c':
7}
(2)、函数参数中包含默认参数的情况
同时存在位置参数、默认参数、*args参数的情况:正确顺序为以下两种情况,切记位置参数均在最前边
T1、(位置参数→默认参数→*args)
其中
- x为1,
- y=1的值被2替换,
- 3,4,5都给args,即args=(3,4,5)
-
def VariableParas_IncludeDefault_Test(x,y=1,*args):
-
print(
'VariableParas_IncludeDefault_Test')
-
print(x,y,args)
-
VariableParas_IncludeDefault_Test(
1,
2,
3,
4,
5)
-
-
-
VariableParas_IncludeDefault_Test
-
1
2 (
3,
4,
5)
T2、(位置参数→*args→默认参数)
其中
- x为1,
- 2,3,4,5都给args,即args=(2,3,4,5)
- y始终为1
-
def ArgsAndDefault_Test(x,*args,y=1):
-
print(
'ArgsAndDefault_Test')
-
print(x,args,y)
-
ArgsAndDefault_Test(
1,
2,
3,
4,
5)
-
-
-
ArgsAndDefault_Test
-
1 (
2,
3,
4,
5)
1
(3)、同时包含当位置参数、默认参数、*args*、*kwargs参数的情况:正确顺序为位置参数→*args*→默认参数→*kwargs)
其中
- x为1,y为2
- 3,4都给args,即args=(3,4)
- a,b分别被替换成5,6
- y=7以字典形式传给kwargs
-
def VariableParas_IncludeAll_Test(x, y, *args, a=8, b=9, **kwargs):
-
print(
'VariableParas_IncludeAll_Test')
-
print(x, y, args, a, b, kwargs)
-
VariableParas_IncludeAll_Test(
1,
2,
3,
4,a=
5,b=
6,c=
7)
-
-
-
VariableParas_IncludeAll_Test
-
1
2 (
3,
4)
5
6 {
'c':
7}
2、深入理解解包(unpacking)星号操作符——*和**
解包(unpacking)操作符,是将python中可迭代对象的值解包的操作符。
- *:单个星号操作符,可以用在任意python提供的可迭代对象上。
- **:两个星号操作符,只能用于字典。
(1)、利用解包操作符*应用于list输出内容本身——print()会先将list解包
理解:print()已经将三个不同的参数作为输入,而不是以一个list作为输入。包操作符(*)来调用函数,而不是用在函数定义中。在这里,print()将list中的单个item作为一个个参数。如下所示,输出不再是list本身,而是list的内容。
-
lists01 = [
1,
2,
3,
4,
5,
6]
-
print(lists01)
-
print(*lists01)
-
-
-
-
[
1,
2,
3,
4,
5,
6]
-
1
2
3
4
5
6
(2)、多个解包操作符*使用方法
用*操作符去解包一个list并传递给函数作为参数,就好像你在传递每一个单独的参数。这表示你可以使用多个解包操作符,从多个lists中获取值并作为参数传递一个函数。
-
def SUMListsByArgs(*args):
-
res =
0
-
for x
in args:
-
res += x
-
print(res)
-
return res
-
-
list01 = [
1]
-
list02 = [
2,
3]
-
list03 = [
4,
5,
6]
-
SUMListsByArgs(*list01, *list02, *list03)
-
-
-
-
-
-
-
21
(3)、利用解包操作符*将list分成三个不同的部分——第一个值、最后一个值和中间的所有值
一个变量被分配给a,最后一个被分配给c,其它的值都被打包成一个list b。
-
lists = [
1,
2,
3,
4,
5,
6]
-
first, *middle, last = lists
-
print(first, middle, last)
-
-
-
-
-
1 [
2,
3,
4,
5]
6
(4)、利用解包操作符*将两个list列表进行合并—使用*解包可迭代对象(列表和字符串)
-
list01 = [
1,
2,
3]
-
list02 = [
4,
5,
6]
-
list03 = [*list01, *list02]
-
print(list03)
-
-
-
-
[
1,
2,
3,
4,
5,
6]
(5)、利用解包操作符*对字符串进行解包操作:两种方法
-
a = [*
"一个处女座的程序猿"]
# 直接解包
-
*b, =
"一个处女座的程序猿"
# *将字符串指定到一个新的list
-
print(a)
-
print(b)
-
-
-
[
'一',
'个',
'处',
'女',
'座',
'的',
'程',
'序',
'猿']
-
[
'一',
'个',
'处',
'女',
'座',
'的',
'程',
'序',
'猿']
(6)、利用解包操作符**解包字典对象——**将两个dict字典进行合并
-
dict01 = {
'AI':
1,
'ML':
2,
'DL':
3}
-
dict02 = {
'CV':
4,
'NLP':
4,
'DS':
4}
-
dict03 = {**dict01, **dict02}
-
print(dict03)
-
-
-
-
{
'AI':
1,
'ML':
2,
'DL':
3,
'CV':
4,
'NLP':
4,
'DS':
4}
-
*args和**kwargs的函数调用使用方法
*args和**kwargs不仅可以在函数定义中使用,还可以在函数调用中使用。在调用时使用就相当于pack(打包)和unpack(解包),类似于元组的打包和解包。
-
def unpackByargs(arg1, arg2, arg3):
-
print(arg1, arg2, arg3)
-
args = (
"一个处女座的程序猿",
2021,
315)
-
unpackByargs(*args)
-
-
-
-
-
一个处女座的程序猿
2021
315
转载:https://blog.csdn.net/qq_41185868/article/details/114849352