函数的参数

参数的定义

函数参数的两大类型
    在定义阶段,在函数名括号内写的变量名,叫做形式参数,简称形参
    在调用阶段,在函数名括号内写的变量名,叫做实际参数,简称实参


实参与形参的关系
    形参就相当于变量名,实参就是形参这个变量名对应的值
    函数调用传参的过程,就相当于给形参赋值的过程

    形参与实参的关系只有在调用函数时,才有效,函数调用结束他们两的关系会自动解除
    只在函数内部有效,函数外部无任何影响


函数的简易架构
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必须与形参对应

 

posted @ 2018-12-09 19:36  Nmdlao  阅读(211)  评论(0编辑  收藏  举报