(小甲鱼python)函数笔记合集三 函数(III)总结 函数的收集参数*args **args 解包参数详解

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

一、基础复习

  1. 函数的基本用法 创建和调用函数 函数的形参与实参等等
  2. 函数的几种参数 位置参数、关键字参数、默认参数等

二、函数的收集参数

1.引言
函数有时不知道用户想传入多少个参数而print()是支持参数可多可少的函数

>>> print("小甲鱼")
小甲鱼
>>> print("小甲鱼","爱","编程")  #打印三个参数
小甲鱼 爱 编程

2.收集参数将参数打包为元祖
收集参数形参的名字前面加上一个星号就行了。

( * args) 称之为Non-keyword Variable Arguments 无关键字参数一个*为参数收集器,类型为元祖类型

举例如下

>>> def myfunc(*args):   #用*args表示收集参数
	print("有{}个参数。".format(len(args)))   #字符串的format方法
	print("第2个参数是:{}".format(args[1]))

>>> myfunc("小甲鱼","中国")
有2个参数。
第2个参数是:中国
>>> 
>>> myfunc(1,2,3,4,5)    
有5个参数。
第2个参数是:2
>>> 

打印形参,收集参数打印出来是元祖而元祖具有打包和解包的能力

>>> def myfunc(*args):
	print(args)

>>> myfunc(1,2,3,4,5)     
(1, 2, 3, 4, 5)    #元祖
>>> 

函数可以同时返回多个值前几节讲过

>>> def myfunc():
	return 1,2,3

>>> myfunc()  
(1, 2, 3)      #返回值以元祖形式打印
>>> x,y,z=myfunc()   #对拿到的返回值解包
>>> x
1
>>> y
2
>>> z
3
>>> 

收集参数*args后面还有其他参数就应该使用使用关键字参数来指定后面的参数

>>> def myfunc(*args):
	print(type(args))

>>> myfunc(1,2,3,4,5)    #收集参数*args类型为元祖
<class 'tuple'>
>>> 
>>> def myfunc(*args,a,b):  
	print(args,a,b)
>>> myfunc(1,2,3,4,5)  #报错4,5应使用关键字参数
Traceback (most recent call last):
  File "<pyshell#39>", line 1, in <module>
    myfunc(1,2,3,4,5)
TypeError: myfunc() missing 2 required keyword-only arguments: 'a' and 'b'
>>> 
>>> myfunc(1,2,3,a=4,b=5)  #正确写法,关键字参数a=4,b=5
(1, 2, 3) 4 5

只能使用关键字参数不能使用位置参数上一讲讲过函数的几种参数 位置参数、关键字参数、默认参数等

>>> def abc(a,*,b,c):      # *后只能用关键字参数
	print(a,b,c)

>>> abc(1,2,3)   #需要1个位置参数b,c也就是2和3需要使用关键字参数。
Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    abc(1,2,3)
TypeError: abc() takes 1 positional argument but 3 were given
>>> 
>>> abc(1,b=2,c=3)  #正确写法
1 2 3

3.收集参数将参数打包为字典

(* args)称之为Non-keyword Variable Arguments 无关键字参数一个星号*为参数收集器,类型为元祖类型
(**kwarge) 称之为keyword Variable Arguments,有关键字参数两个星号 ** 为字典形式的收集参数

举例如下
字典是以键值对出现的如a=1等号左边是键右边是值。

>>> def myfunc(**kwargs):
	print(kwargs)

>>> myfunc(a=1,b=2,c=3)    #关键字参数
{'a': 1, 'b': 2, 'c': 3}
>>> 
>>> def myfunc(a,*b,**c):     #两种收集参数方法混合使用
	print(a,b,c)

>>> myfunc(1,2,3,4,x=5,y=6)   #1为位置参数2,3,4为元祖5,6为字典
1 (2, 3, 4) {'x': 5, 'y': 6}

字符串的format方法同时使用一个星号和两个星号作为收集参数的情况

>>> help(str.format)
Help on method_descriptor:

format(...)
    S.format(*args, **kwargs) -> str
    
    Return a formatted version of S, using substitutions from args and kwargs.
    The substitutions are identified by braces ('{' and '}').

>>> 

4.解包参数
一个星号和两个星号在函数上也有使用在形参上使用我们称为参数的打包在实参上使用则起到了相反的结果。
一个星号* 实际参数将元祖解包

>>> args=(1,2,3,4)
>>> def myfunc(a,b,c,d):
	print(a,b,c,d)

>>> myfunc(args)   #报错需要4个参数但只传入一个参数
Traceback (most recent call last):
  File "<pyshell#77>", line 1, in <module>
    myfunc(args)
TypeError: myfunc() missing 3 required positional arguments: 'b', 'c', and 'd'
>>> 
>>> myfunc(*args)   #对参数的解包args不在是一个元祖它被解包成1,2,3,4传递到a,b,c,d四个形参里面
1 2 3 4

两个星号**实际参数将字典解包成关键字参数

>>> kwargs={'a':1,'b':2,'c':3,'d':4}
>>> myfunc(**kwargs)   #字典解包
1 2 3 4
>>> 

课后题

  1. 在函数定义中带一个星号的形参如 def func(*x)和带两个星号的形参如 def func(**x)有什么区别
    答都是收集参数但是打包方式不同。一个星号是将收集到的参数打包为元组的形式两个星号是将收集到的参数打包为字典的形式。

2. 请问下面代码会打印什么呢

>>> def func(a, b=4, c=5):
...     print(a, b, c)
...        
>>> func(1, 2)
>>> # 请问这里会打印什么内容

>>> func(1, 2)
1 2 5

解析1 和 2 作为位置参数传递给了形参 a 和 b并且 c 在调用中被忽略了从而使用默认值 5。
3. 请问下面代码会打印什么呢

>>> def func(x, *y, z=3):
...     print(x, y, z)
...
>>> func(1, 1, 2, 3, 5)
>>> # 请问这里会打印什么内容

>>> func(1, 1, 2, 3, 5)
1 (1, 2, 3, 5) 3

解析由于形参 y 是定义为收集参数所以除了第一个实参 1 给到 x其它的实参1、2、3、5都给到了 yz 就只能使用默认值 3如果想要给 z 赋值需要使用关键字参数才行。
4.请问下面代码会打印什么呢

>>> def func(x, *y, **z):
...     print(x, y, z)
...
>>> func(1, 2, 3, 4, y=5)
>>> # 请问这里会打印什么内容

>>> func(1, 2, 3, 4, y=5)
1 (2, 3, 4) {'y': 5}

解析实参 1 传给第一个位置参数 x接着的 234 传给元组收集参数 y最后一个 y=5 传给字典收集参数 z。
5.请问下面代码会打印什么呢

>>> def func(x, *y, **z):
...     print(x, y, z)
...
>>> func(1, 2, x=3, y=4, z=5)
>>> # 请问这里会打印什么内容

答会报错。

>>> func(1, 2, x=3, y=4, z=5)
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    func(1, 2, x=3, y=4, z=5)
TypeError: func() got multiple values for argument 'x'

解析虽然说映射形式的多个参数会被字典形的收集参数统一收集但这里由于 x 是第一个形参的名字从而产生冲突Python 搞不懂 x=3 的含义是要通过关键字参数赋值还是被收集参数 z 获取……所以注意代码一定不要有二义性否则都会出错。
6.请问下面代码会打印什么呢

>>> def func(x, y, z=3):
...     print(x, y, z)
...
>>> func((1, 2), *(3, 4))
>>> # 请问这里会打印什么内容

>>> func((1, 2), *(3, 4))
(1, 2) 3 4

解析第一个实参 (1, 2) 是以元组的形式传递所以作为整个传递给形参 x第二个参数 * (3, 4) 虽说也是元组但作为实参前面带个星号*表示解包操作会将 3 和 4 拆开后再分别传递给形参 y 和 z。

题目来自小甲鱼函数(III)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: python