4-[函数]-参数
1.形参,实参
- 形参变量
只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量
- 实参
可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
2,默认参数
(1)相同CN可以变为默认参数
发现 country 这个参数 基本都 是"CN", 就像我们在网站上注册用户,像国籍这种信息,你不填写,默认就会是 中国, 这就是通过默认参数实现的,把country变成默认参数非常简单
(2)默认参数必须放在最后面
另外,你可能注意到了,在把country变成默认参数后,我同时把它的位置移到了最后面,为什么呢?
按位置一一对应,默认参数必须放在位置参数后面
(3)修改默认参数
3.位置参数,关键参数
(1)位置参数
(2)关键参数
- 正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可(指定了参数名的参数就叫关键参数),
- 但记住一个要求就是,关键参数必须放在位置参数(以位置顺序确定对应关系的参数)之后
但绝不可以这样:关键字参数应该放在 位置参数后
stu_register("王山炮",course='PY',22,country='JP' )
当然这样也不行: 给age赋值2次
stu_register("王山炮",22,age=25,country='JP' )
4.非固定参数 *args : 元组
(1)如果参数中出现,*users,传递的参数就可以不是固定个数参数,传过来的参数打包成元组
# 报警, 1个运维人员 def send_alert(mgs, user): pass send_alert('出现error,请处理', 'alex')
# 报警,10个运维人员 def send_alert(mgs, *users): #('alex', 'xxx', 'ttt') for u in users: print('%s->%s'%(mgs,u)) send_alert('出现error,请处理', 'alex', 'xxx','ttt')
# 运行结果 出现error,请处理->alex 出现error,请处理->xxx 出现error,请处理->ttt
(2)如果穿过来的是list,会把他作为元组的第一个元素
# 报警,10个运维人员 def send_alert(mgs, *users): # ('alex', 'xxx','ttt')---> (['alex', 'xxx', 'ttt'],) for u in users: print('%s->%s'%(mgs,u)) #send_alert('出现error,请处理', 'alex', 'xxx','ttt') send_alert('出现error,请处理', ['alex', 'xxx','ttt'])
# 运行结果 出现error,请处理->['alex', 'xxx', 'ttt']
(3)传入list,使用一个星号
不光列表,任何序列类型数据对象,比如字符串、元组都可以通过这种方式将内部元素逐一作为参数,传递给函数。而字典,则会将所有的key逐一传递进去。
def send_alert(mgs, *users): # ('alex', 'xxx','ttt')---> ('alex', 'xxx', 'ttt') print(users) for u in users: print('%s->%s'%(mgs,u)) send_alert('出现error,请处理', *['alex', 'xxx','ttt']) # 运行结果 ('alex', 'xxx', 'ttt') 出现error,请处理->alex 出现error,请处理->xxx 出现error,请处理->ttt
(4)位置参数不能放在*args后面
(4)关键字参数可以放在*args后面
5.非固定参数**kwargs :字典
(1)两个星表示接受键值对的动态参数,数量任意。调用的时候会将实际参数打包成字典。例如:
(2)使用两个星号!字典传给它
(3)“万能”参数
当*args
和**kwargs
组合起来使用,理论上能接受任何形式和任意数量的参数,在很多代码中我们都能见到这种定义方式。需要注意的是,*args
必须出现在**kwargs
之前。
def func(*args, **kwargs): for arg in args: print(arg) for kwg in kwargs: print(kwg, kwargs[kwg]) lis = [1, 2, 3] dic = { 'k1': 'v1', 'k2': 'v2' } func(*lis, **dic)
6.拆包 * **
- 把元组拆成一个个,当成参数传递
- 把字典拆成一对对键值对,当成参数传递
(1)拆包之前
###### 拆包之前 def test(a,b,c=33,*args,**kwargs): print(a) print(b) print(c) print(args) print(kwargs) #test(11,22,33,44,55,66,task=99,done=98) A = (44,55,66) B = {"name":"alex","age":18} test(11,22,33,A,B) #### 运行结果 11 22 33 ((44, 55, 66), {'age': 18, 'name': 'alex'}) #A,B是传递的参数 {} #没有传入命名参数
(2)拆包之后
#### 拆包之后 def test(a,b,c=33,*args,**kwargs): print(a) print(b) print(c) print(args) print(kwargs) #test(11,22,33,44,55,66,task=99,done=98) A = (44,55,66) B = {"name":"alex","age":18} test(11,22,33,*A,**B) #### 运行结果 11 22 33 (44, 55, 66) {'age': 18, 'name': 'alex'}