一、形参与实参

  1、形参:在定义函数阶段所定义的参数称为形式参数,即形参,相当于变量名。

  2、实参:在调用函数阶段所传入的参数称为实际参数,即实参,相当于变量值。

def func(a, b):  # 定义函数时的参数a,b即为形参
    res = a + b
    return res
num_sum = func(1, 2)  # 调用函数时的参数1,2即为实参

  3、形参与实参的关系:

    ①在调用阶段,实参的值会绑定给形参,类似于变量的赋值操作,变量值绑定给变量名。

    ②这种绑定关系只能在函数体内使用。

    ③调用函数时,实参与形参的绑定关系生效,函数体代码执行完,即函数调用完成后即解除绑定关系。

  4、实参传入值的形式:

    ①直接传值:

def func(a,b):
    pass
func(1,2)  # 直接把值填入括号内作为实参传入

    ②通过变量名:

def func(a,b):
    pass
a = 1
b = 2
func(a,b)  # 在括号内填入变量名a,b就相当于把它们对应的值1,2填入

    ③把系统功能或自定义函数的返回值传入:

def func(a,b):
    res = a+b
    return res
func(int('1'),func(2,3))  # 返回值作为实参

二、形参与实参的具体使用

  1、位置参数:按照从左到右的顺序依次定义的参数称为位置参数。

    ①位置形参:在函数的定义阶段,从左到右依次定义的参数名,必须被传值,传入值的数量要与参数名数量完全一致。

def func(a,b):
    pass
func(1)  
func(1,2,3)
# 作为传入值的实参数量与形参数量相比,过多过少都会报错

    ②位置实参:在函数的调用阶段,从左到右依次传入的参数值,按照位置与形参一一对应。

def func(a,b):
    pass
func(1,2)  #值 1 对应形参 a ,值 2 对应形参 b

  2、关键字参数:在函数的调用阶段,按照key=value的形式传入值,key对应形参名,value对应传入值,顺序无影响,但数量需要对应一致。

def func(a, b):
    pass
func(b=2, a=1)  # 以关键字形式传参数值,不用必须按照从左到右依次的顺序
func(b=2, c=3)  # 不能为不存在的参数传值,报错

  3、位置参数与关键字参数混用的原则:

    ①位置参数必须放在关键字参数前面。

def func(a, b):
    pass
func(b=2,1)  # 报错

    ②不能为同一个参数重复传值。

def func(a, b):
    pass
func(1,a=2)  # 报错

  4、默认参数:

    ①定义:在函数的定义阶段,就已经被赋值的形参,称为默认参数,这种函数的调用阶段,因为该参数已被赋值,可以不用再为其赋值,若赋值则覆盖默认值。

def func(a, b=2):
    pass
func(1)  # 只对形参名 a 赋值为 1,b 仍为默认值 2
func(1,3)  # 实参对 b 传入值 3 ,则 b 的值会被覆盖为 3

    ②位置参数与默认参数混用的原则:位置参数必须放在默认参数前面。

def func(a=1,2):  #  报错
    pass

    ③默认参数的约定规范:赋值类型应该为不可变类型,否则有可能出现函数体不封闭的情况。

x = [22,33]
def func(a,b=x):
    print(a,b)
func(1)  # 结果为 1 [22, 33]
x[0] = 44
func(1)  # 结果为 1 [44, 33],默认参数值因列表的特性而导致因外界变化而同步变化了

  5、可变长度参数:*与**的用法。

    ①定义:可变长度是指在调用函数时,传入值的数量可能不固定,因为形参与实参需要遵循数量一致的原则,那么数量溢出的实参需要有对应的形参来接收。

    ②可变长度位置参数:

      Ⅰ:可变长度位置形参:形式为,*形参名,溢出的位置参数会组成为一个元组赋值给该形参名,此种形参名原则上可以是任意合法形参名,但约定上用*args。

def func(a,*args):
    pass
func(1,2,3,4,5,6)  # 相当于 args = tuple(2,3,4,5,6)

      Ⅱ:可变长度位置实参:形式为,*可遍历类型,会先解压出各个元素,再依次赋值给对应形参名。

def func(a,b,c,d,e,f):
    pass
func(1,*[2,3,4,5,6])  # 相当于把 2,3,4,5,6 依次赋值给 b,c,d,e,f

      Ⅲ:形参与实参都为可变长度位置参数:先把可变长度位置实参解压,再由可变长度位置形参接收。

def func(a,*args):
    pass
func(1,*[2,3,4,5,6])  # 先把 2,3,4,5,6解压出来,再由 args 接收组成 tuple(2,3,4,5,6)

    ③可变长度关键字参数:

      Ⅰ:可变长度关键字形参:形式为,**形参名,溢出的关键字参数会组成为一个字典赋值给该形参名,此种形参名原则上可以是任意合法形参名,但约定上用**kwargs。

def func(a,**kwargs):
    pass
func(a=1,b=2,c=2)  # 相当于 kwargs = dict{'b':2,'c':3}

      Ⅱ:可变长度关键字实参:形式为,**dict,会先把字典中的键值对解压成key=value的形式,再赋值给对应形参名。

def func(a,b,c):
    pass
func(a=1,**{'b':2,'c':3})  # 相当于以 b=2,c=3的形式赋值给对应形参名 

      Ⅲ:形参与实参都为可变长度关键字参数:先把可变长度关键字实参解压,再由可变长度关键字形参接收。

def func(a,**kwargs):
    pass
func(a=1,**{'b':2,'c':3})  # 把 {'b':2,'c':3} 解压为 b=2,c=3,再由 kwargs 接收组成 dict{'b':2,'c':3}

    ④可变长度位置参数与可变长度关键字参数混用:即*args与**kwargs。

      Ⅰ:原则:根据位置参数必须放在关键字参数前面的原则,*args也必须放在**kwargs的前面。

def func(a,*args,**kwargs):
    pass
func(1,2,3,4,e=5,f=6)  # 即,a=1,args=tuple(2,3,4),kwargs={'e':5,'f':6}

      Ⅱ:万能嵌套:

def func1(a, b, c, d, e):
    pass
def func2(*args, **kwargs):
    func1(*args, **kwargs)
func2(1, 2, 3, d=4, e=5)
# 此时无论func2传入多少任意类型实参,都会被func2的形参分类压缩收集,
# 然后func2的形参被赋值后再作为func1的实参解压传给func1的对应形参,
# 这样当调整func1的参数数量时完全不需要调整func2

 

posted on 2020-01-03 07:01  焚音留香  阅读(365)  评论(0编辑  收藏  举报