参数的定义
函数参数的两大类型 在定义阶段,在函数名括号内写的变量名,叫做形式参数,简称形参 在调用阶段,在函数名括号内写的变量名,叫做实际参数,简称实参 实参与形参的关系 形参就相当于变量名,实参就是形参这个变量名对应的值 函数调用传参的过程,就相当于给形参赋值的过程 形参与实参的关系只有在调用函数时,才有效,函数调用结束他们两的关系会自动解除 只在函数内部有效,函数外部无任何影响 函数的简易架构 def 函数名(x,y): ''' 函数的作用 :param x: 对形参x的解释 :param y: 对形参y的解释 :return: 对函数返回值的解释 ''' print('hello world') return 'haha'
位置参数和关键字参数
位置参数定义: 函数在定义阶段,变量名按照位置从左到右进行书写 位置参数在调用时,必须给位置参数传参 传参个数必须与位置参数个数一一对应 def max_2(x,y): if x > y: return x return y print(max_2(10,222)) 关键字参数(指名道姓的传入参数): def max1_2(x,y): if x > y: return x return y print(max1_2(x=19,y=20)) print(max1_2(y=999,x=1)) print(max1_2(10,y=20)) 在函数调用阶段,位置参数可以和关键字参数混合使用 注意事项: 1.位置参数必须在关键字参数前面 2.同一个形参不能被多次赋值
默认值参数和可变长参数
默认值参数 定义:在函数定义阶段,有些形参已经进行赋值了 在调用中,可以不用对默认值参数传参,默认使用定义阶段绑定好的值 在调用中,可以对默认值参数传参,会使用你传的参数 定义阶段,默认值参数必须放置位置参数后面 def max2_2(x,y=100): if x > y: return x return y 默认值参数的使用场景主要应用在,某个形参接收到的值比较单一时,通常可以考虑把它设成默认值参数 # 参数陷阱 def defult_param(a,l = []): l.append(a) print(l) defult_param('alex') defult_param('egon') ''' ['alex'] ['alex', 'egon'] ''' # 解决方法一 defult_param('alex',[]) defult_param('egon',[]) # 解决方法二 def fnc1(a,l = None): if l == None: l = [] l.append(a) print(l) fnc1('alxe') fnc1('egon') 函数在定义阶段,函数内所使用的的变量名已经全部初始化 不会随着函数调用位置的改变,影响内部的值 无论函数在哪调用, 都会跑到函数定义的地方去执行函数, 形参中用到的值都是往函数定义阶段上方去找 可变长参数 站在调用函数传递实参的角度 实参的个数不固定的情况 也就意味形参也不固定 站在形参的角度 可以用*和**来接收多余的(溢出的)位置参数和关键字参数 站在形参的角度 看 * 会将实参中多余的值,以元组的形式传递给* 后面的形参名 def fnc(x,*y): print(x,y) fnc(1,2,3,4,5,6,7,) # 1 (2, 3, 4, 5, 6, 7) 站在实参的角度看 * def fnc(x,y,z): print(x,y,z) # 1 2 3 fnc(*[1,2,3]) 在实参中加* ,会将列表中的元素打散成位置实参一一传入等价于fnc(1,2,3) def fnc(x,*y): print(x,y) # 1 (1, 2, 3, 3, 3, 3, 3) fnc(1,*[1,2,3,3,3,3,3]) # *在形参中只能接收溢出的位置参数,不能接收关键字实参 实参中* 只能加列表,元组,集合,字符串 * 的内部可以看成for循环 站在形参的角度看** def fnc(x,**y): print(x,y) # 1 {'a': 1, 'b': 2, 'c': 3} fnc(1,a=1,b=2,c=3) 将多余的关键词传参转换成字典,字典的key就是关键字的名字,并传递给** 后面的形参名 站在实参的角度看** def fnc(x,y,z): print('my name is %s my age %s my favorite %s'%(x,y,z)) # my name is cly my age 17 my favorite av fnc(**{'x':'cly','y':17,'z':'av'}) # 等价于fnc( x = 'cly' , y = 17 , z = 'av') ,这里的key必须与形参对应 # 需求 你写的函数 无论调用者按照正确传参的方式无论怎么传 你的函数都能够正常执行 def fnc(*x,**y): print(x,y) fnc() # 只要按正常传参方式,随便传,你的函数都能执行 总结 * 和 ** *在形参中,接收实参溢出的位置参数 将其以元组的形式传给*后面的形参名 **在形参中,接收实参溢出的关键词参数 将其以字典的形式传给**后面的形参名 *在实参中,将列表,元组等打散成位置参数传入实参中 **在实参中,将字典打散成 key = value形式,而且key必须与形参对应