Python编程学习:让函数更加灵活的*args和**kwargs(设计不同数量参数的函数)的简介、使用方法、经典案例之详细攻略

举报
一个处女座的程序猿 发表于 2021/03/28 00:55:26 2021/03/28
【摘要】 Python编程学习:让函数更加灵活的*args和**kwargs(设计不同数量参数的函数)的简介、使用方法、经典案例之详细攻略       目录 *args和**kwargs(设计不同数量的参数函数)的简介 1、*用法:统计一个班内报名学篮球的同学,但是不知道有多少个人名 2、**用法:统计某个人的爱好,但是不知道这个人有多少种爱...

Python编程学习:让函数更加灵活的*args和**kwargs(设计不同数量参数的函数)的简介、使用方法、经典案例之详细攻略

 

 

 

目录

*args和**kwargs(设计不同数量的参数函数)的简介

1、*用法:统计一个班内报名学篮球的同学,但是不知道有多少个人名

2、**用法:统计某个人的爱好,但是不知道这个人有多少种爱好

*args和**kwargs的函数定义使用方法——如何设计不同数量的参数的函数

T1、最基础做法——创建一个list作为参数传入(适合能枚举所有值的情况)

T2、传递可变数量的位置参数的关键用法之*args和**kwargs

1、*args的简介、使用方法(列表/元祖的形式,表示任何多个无名参数)

(1)、*args的简介、使用方法

(2)、解决上边的问题——如何设计不同数量的参数的函数

2、**kwargs的简介、使用方法(字典的形式,表示一个一个有着对应关系的关键字参数)

(1)、**kwargs的简介、使用方法

(2)、解决上边的问题——如何设计不同数量的参数的函数

知识点拓展:函数中参数的顺序——如何接受可变数量的位置参数和命名参数?

1、arg、*args、**kwargs的混合使用简介——args和kwargs组合起来可以传入任意个数的参数,这在参数未知的情况下是很有效的,同时加强了函数的可拓展性。

(1)、函数参数中不包含默认参数的情况

(2)、函数参数中包含默认参数的情况

(3)、同时包含当位置参数、默认参数、*args*、*kwargs参数的情况:正确顺序为位置参数→*args*→默认参数→*kwargs)

2、深入理解解包(unpacking)星号操作符——*和**

(1)、利用解包操作符*应用于list输出内容本身——print()会先将list解包

(2)、多个解包操作符*使用方法

(3)、利用解包操作符*将list分成三个不同的部分——第一个值、最后一个值和中间的所有值

(4)、利用解包操作符*将两个list列表进行合并—使用*解包可迭代对象(列表和字符串)

(5)、利用解包操作符*对字符串进行解包操作:两种方法

(6)、利用解包操作符**解包字典对象——**将两个dict字典进行合并

*args和**kwargs的函数调用使用方法


 

 

 

*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,即打包关键字参数

  
  1. def a_function(*args, **kwargs):
  2. pass

 

1、*用法:统计一个班内报名学篮球的同学,但是不知道有多少个人名


  
  1. # 1、*用法:统计一个班内报名学篮球的同学,但是不知道有多少个人名
  2. def CountLearnBasketballs(*basketNums):
  3. print("People who study basketball have:" + ", ".join(basketNums))
  4. # (1)、用在函数定义中
  5. CountLearnBasketballs('马云','马化腾','李彦宏','刘强东','王兴','丁磊')
  6. # (2)、用在函数调用中
  7. basketNames = ('马云','马化腾','李彦宏','刘强东','王兴','丁磊')
  8. CountLearnBasketballs(*basketNames)

 

2、**用法:统计某个人的爱好,但是不知道这个人有多少种爱好


  
  1. # 2、**用法:统计某个人的爱好,但是不知道这个人有多少种爱好
  2. def CountHobbies(**hobbies):
  3. print("This person's hobbies include...")
  4. for category, fave in hobbies.items():
  5. print(f"{category}: {fave}")
  6. CountHobbies(sports='basketball', arts='drawing', learning='reading')

 

 

*args和**kwargs的函数定义使用方法——如何设计不同数量的参数的函数

T1、最基础做法——创建一个list作为参数传入(适合能枚举所有值的情况)


  
  1. def SUMListsByLists(MoreParasLists):
  2. sum_lists = 0
  3. for a in MoreParasLists:
  4. sum_lists += a
  5. return sum_lists
  6. MoreParasLists = [1, 2, 3, 4, 5, 6]
  7. print(SUMListsByLists(MoreParasLists))
  8. 21

 

 

 

T2、传递可变数量的位置参数的关键用法之*args和**kwargs

1、*args的简介、使用方法(列表/元祖的形式,表示任何多个无名参数)

(1)、*args的简介、使用方法

        *args 用来将参数打包成tuple给函数体调用,是非关键字参数,用于元组。此时,不是向函数传递一个list,而是接收位置参数,其原理是传递三个不同的位置参数

  • 上边的SUMListsByArgs会获取所有输入的参数,并将它们打包成一个可迭代的简单对象。
  • 该对象可命名为args或者其它名称args123,主要是前缀有“*”号,它是解包(unpacking)操作符。但是,该可迭代对象并非是一个list(可变的),而是一个元组tuple(不可变的)

  
  1. def args01(*args):
  2. print(args, type(args))
  3. args01('一个处女座的程序猿')
  4. def args02(x, y, *args):
  5. print(x, y, args)
  6. args02(1, 2, 3, 4, '我是','一个处女座的程序猿')
  7. ('一个处女座的程序猿',) <class 'tuple'>
  8. 1 2 (3, 4, '我是', '一个处女座的程序猿')

 

 

(2)、解决上边的问题——如何设计不同数量的参数的函数


  
  1. def SUMListsByArgs(*args):
  2. sum_lists = 0
  3. # Iterating over the Python args tuple
  4. for a in args:
  5. sum_lists += a
  6. return sum_lists
  7. print(SUMListsByArgs(1, 2, 3, 4, 5, 6))
  8. 21

 

 

2、**kwargs的简介、使用方法(字典的形式,表示一个一个有着对应关系的关键字参数)

(1)、**kwargs的简介、使用方法

     **kwargs将参数打包关键字参数以dict形式给函数体调用。其实,**kwargs工作原理和*args有点类似,但不是接收位置参数,而是接收关键字(keyword)参数(也叫被命名的参数)。同样地,该对象可命名为kwargs或者其它名称kwargs123,主要是前缀有“**”号,它是解包(unpacking)操作符。但是该可迭代对象是字典dict,所以获取返回值要使用.values()


  
  1. def kwargs01(**kwargs):
  2. print( kwargs, type(kwargs))
  3. kwargs01(a='一个处女座的程序猿')
  4. def kwargs02(**kwargs):
  5. print(kwargs)
  6. kwargs02(a='我是', b='一个处女座的程序猿', c='!')
  7. {'a': '一个处女座的程序猿'} <class 'dict'>
  8. {'a': '我是', 'b': '一个处女座的程序猿', 'c': '!'}

 

 

(2)、解决上边的问题——如何设计不同数量的参数的函数


  
  1. def StrConnect(**kwargs):
  2.     strs01='';strs02=''
  3.     # Iterating over the Python kwargs dictionary
  4.     for b in kwargs:
  5.         strs01 += b
  6.     for a in kwargs.values():
  7.         strs02 += a
  8.     print('keys集合:',strs01)
  9.     print('values集合:',strs02)
  10.     return strs02
  11. print(StrConnect(a="大家好", b=",", c="我是", d="一个处女座的程序猿", e="!"))
  12. keys集合: abcde
  13. values集合: 大家好,我是一个处女座的程序猿!
  14. 大家好,我是一个处女座的程序猿!

 

 

知识点拓展:函数中参数的顺序——如何接受可变数量的位置参数和命名参数?

1、arg、*args、**kwargs的混合使用简介——args和kwargs组合起来可以传入任意个数的参数,这在参数未知的情况下是很有效的,同时加强了函数的可拓展性。

      args和kwargs组合起来可以传入任意个数的参数,这在参数未知的情况下是很有效的,同时加强了函数的可拓展性。

  • 顺序很重要,非默认参数必须在默认参数之前处理,因此*args在**kwargs的前面;
  • 参数的正确顺序:位置参数→*args参数→**kwargs参数、非默认参数→默认参数;参数arg、*args、**kwargs三个参数的位置必须是一定的。

  
  1. def VariableParasNum_Test(arg,*args,**kwargs):
  2. print('VariableParasNum_Test')
  3. print(arg,args,kwargs)
  4. VariableParasNum_Test(1,2,3,4,a=5, b=6, c=7)
  5. VariableParasNum_Test
  6. 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

  
  1. def VariableParasNum_NoDefault_Test(x, y, *args,**kwargs):
  2. print('VariableParasNum_NoDefault_Test')
  3. print(x, y, args, kwargs)
  4. VariableParasNum_NoDefault_Test(1,2,3,4,a=5,b=6,c=7)
  5. VariableParasNum_NoDefault_Test
  6. 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)

  
  1. def VariableParas_IncludeDefault_Test(x,y=1,*args):
  2. print('VariableParas_IncludeDefault_Test')
  3. print(x,y,args)
  4. VariableParas_IncludeDefault_Test(1,2,3,4,5)
  5. VariableParas_IncludeDefault_Test
  6. 1 2 (3, 4, 5)

 

T2、(位置参数→*args→默认参数)

其中

  • x为1,
  • 2,3,4,5都给args,即args=(2,3,4,5)
  • y始终为1

  
  1. def ArgsAndDefault_Test(x,*args,y=1):
  2. print('ArgsAndDefault_Test')
  3. print(x,args,y)
  4. ArgsAndDefault_Test(1,2,3,4,5)
  5. ArgsAndDefault_Test
  6. 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

  
  1. def VariableParas_IncludeAll_Test(x, y, *args, a=8, b=9, **kwargs):
  2. print('VariableParas_IncludeAll_Test')
  3. print(x, y, args, a, b, kwargs)
  4. VariableParas_IncludeAll_Test(1,2,3,4,a=5,b=6,c=7)
  5. VariableParas_IncludeAll_Test
  6. 1 2 (3, 4) 5 6 {'c': 7}

 

 

 

2、深入理解解包(unpacking)星号操作符——*和**

解包(unpacking)操作符,是将python中可迭代对象的值解包的操作符。

  • *:单个星号操作符,可以用在任意python提供的可迭代对象上。
  • **:两个星号操作符,只能用于字典

 

(1)、利用解包操作符*应用于list输出内容本身——print()会先将list解包

理解:print()已经将三个不同的参数作为输入,而不是以一个list作为输入。包操作符(*)来调用函数,而不是用在函数定义中。在这里,print()将list中的单个item作为一个个参数。如下所示,输出不再是list本身,而是list的内容。


  
  1. lists01 = [1, 2, 3, 4, 5, 6]
  2. print(lists01)
  3. print(*lists01)
  4. [1, 2, 3, 4, 5, 6]
  5. 1 2 3 4 5 6

 

(2)、多个解包操作符*使用方法

用*操作符去解包一个list并传递给函数作为参数,就好像你在传递每一个单独的参数。这表示你可以使用多个解包操作符,从多个lists中获取值并作为参数传递一个函数。


  
  1. def SUMListsByArgs(*args):
  2. res = 0
  3. for x in args:
  4. res += x
  5. print(res)
  6. return res
  7. list01 = [1]
  8. list02 = [2, 3]
  9. list03 = [4, 5, 6]
  10. SUMListsByArgs(*list01, *list02, *list03)
  11. 21

 

 

(3)、利用解包操作符*将list分成三个不同的部分——第一个值、最后一个值和中间的所有值

一个变量被分配给a,最后一个被分配给c,其它的值都被打包成一个list b。


  
  1. lists = [1, 2, 3, 4, 5, 6]
  2. first, *middle, last = lists
  3. print(first, middle, last)
  4. 1 [2, 3, 4, 5] 6

 

 

(4)、利用解包操作符*将两个list列表进行合并—使用*解包可迭代对象(列表和字符串)


  
  1. list01 = [1, 2, 3]
  2. list02 = [4, 5, 6]
  3. list03 = [*list01, *list02]
  4. print(list03)
  5. [1, 2, 3, 4, 5, 6]

 

 

(5)、利用解包操作符*对字符串进行解包操作:两种方法


  
  1. a   = [*"一个处女座的程序猿"]    # 直接解包
  2. *b, =   "一个处女座的程序猿"     # *将字符串指定到一个新的list 
  3. print(a)
  4. print(b)
  5. ['一', '个', '处', '女', '座', '的', '程', '序', '猿']
  6. ['一', '个', '处', '女', '座', '的', '程', '序', '猿']

 

 

(6)、利用解包操作符**解包字典对象——**将两个dict字典进行合并


  
  1. dict01 = {'AI':1, 'ML':2, 'DL':3}
  2. dict02 = {'CV':4, 'NLP':4, 'DS':4}
  3. dict03 = {**dict01, **dict02}
  4. print(dict03) 
  5. {'AI': 1, 'ML': 2, 'DL': 3, 'CV': 4, 'NLP': 4, 'DS': 4}


 

 

*args和**kwargs的函数调用使用方法

       *args和**kwargs不仅可以在函数定义中使用,还可以在函数调用中使用。在调用时使用就相当于pack(打包)和unpack(解包),类似于元组的打包和解包。


  
  1. def unpackByargs(arg1, arg2, arg3):
  2. print(arg1, arg2, arg3)
  3. args = ("一个处女座的程序猿", 2021, 315)
  4. unpackByargs(*args)
  5. 一个处女座的程序猿 2021 315

 

 

 

 

文章来源: yunyaniu.blog.csdn.net,作者:一个处女座的程序猿,版权归原作者所有,如需转载,请联系作者。

原文链接:yunyaniu.blog.csdn.net/article/details/114849352

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。