函数的参数

一、行参和实参介绍

  函数的参数分为形式参数和实际参数,简称为形参和实参

  形参:是在函数定义阶段中,即定义函数时括号里面的参数,本质是一个变量,是用来接收外部传来的值

  实参:是在函数调用阶段中,即调用函数时括号里面的值,值是一个变量、常量、表达式或三则的组合

    # 常量:my_min(1,2)

    # 变量:a = 1

        b =2

        my_min(a,b)

    # 表达式:a = 2

         my_min(10*2,10*my_min(3,4))

    # 三者组合:b = 2

          my_min(1,b,10*my_min(3,4))

  形参和实参的关系:

    1.在调用阶段,实参(值)会绑定给形参(变量名)

    2.这种绑定关系只能在函数体内使用

    3.形参和实参的绑定关系是在函数调用时生效,当哈数调用结束后解除绑定关系

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

  1.位置参数:指在定义函数按照顺序定义的参数,为位置形参;在调用时按照形参的顺序传值,为位置实参

    def fount(x,y):  # 在定义函数时,从左到右依次定义的参数,称之为位置形参,必须被传值

      print(x,y)

    fount(1,2)   # 调用函数时,按照从左到右依次定义的参数,称之为位置实参,必须与位置形参一一对应

  注:定义函数时,形参定义了几个函数,在调用阶段也必须传几个值,调用函数中定义的参数必须喝定义函数时的参数保持一致,按照从左到右的顺序进行对应

  2.关键字参数:在调用函数时,实参以key=value方式进行,称之为关键字参数,用这种方式定义的实参,可以不用按照顺序,但是任然要给指定的形参赋值

    def fount(x,y):

      print(x,y)

    fount(y=2,x=1)

  注:位置参数和关键字参数可以混合使用,但是关键字从参数必须放在位置参数后面,并且不能给同一个参数多次赋值

    举例:def fount(x,y):

         print(x,y)

       fount(1,y=2)  # 关键字参数必须放在位置参数后面,并且不能多次赋值

       #fount(1,2,y=3)  # 这种就会报错,位置参数为对应关系,这是1赋值给了x,2赋值给了y,后面进行了关键字参数又给y进行了赋值,多次给y赋值了

  3.默认参数:在定义函数阶段时就已经给形参进行了赋值,这样称之为默认参数(也可以称之为默认形参),这里赋值是赋予的是内存地址

    默认参数使用一:在定义函数阶段给形参赋值后,在调用阶段可以不用为其在赋值

      def fount(x,y=2):

        print(x,y)  # 输出结果:1,2

      fount(1)  # 在定义函数时就已经给形参进行了赋值,这时在调用阶段时就不用在给形参赋值

  注:默认参数主要用于:在函数有多个参数时,其中有的参数不经常该变,大部分时间都是这个值,特殊情况下才会改变这个值,这时使用默认参数

    默认参数使用二:在定义函数阶段给形参赋值户,在调用阶段给形参进行赋值

      def fount(x,y=2):

        print(x,y)  # 输出结果:1,3

      fount(1,3)  # 定义是已经给了给参数进行了赋值,但是在调用时又给其赋值了,这时形参就会以调用时的值为准,输出结果就会是1,3

    默认参数使用三:默认参数的值通常应该设为不可变类型,如果是可变类型在调用函数时就不能预知到函数的结果了,函数体主要实现该函数的功能即可

            函数最理想的状态:函数调用只跟函数本身有关系,不受外界代码的影响

      def fount(x.y=[]):  # 这里默认参数设为了可变类型,在函数体中进行实现代码就不能预知到该函数的结果

           y.append(x)

           print(x,y)  # 这里就不能预知到输出的y的值了,这里就会输出1 [1],2 [1,2

      fount(1)  

      funnt(2)

      可以修上面代码为:

        def fount(x,y=None):

          if y is None:

            y=[]

          y.append(x)

          print(x,y)  # 这里就可以预知到y的值了,输出:1 [1],2 [2]

        fount(1)

        fount(2)

    注:位置形参和默认形参可以混合使用,但是默认形参必须放在位置形参的后面,默认形参仅能在函数定义阶段被赋值一次

      举例:y = 2

        def fount(x,arg =y):  # 默认形参必须放在位置形参后面,并且默认参数已经赋值了

          print(x,arg)  # 打印结果为:1,2

        y = 3  # 在定义阶段已经被赋值了,这里的y和函数中的y没有任何关系

        fount(1)  # 为x赋值

三、位置参数、默认参数运用场景

  位置参数:当值经常变化的情况下,这时定义为位置参数

  默认参数:当值不经常变化,只是在少数情况是才会变化,这时可以使用默认参数,在调用时大多数情况就可以不用传值了,少数情况下进行传值

四、可变长度的参数(*与**的使用)

  位置参数的长度可变:指的是在调用函数时,实参的个数可以不固定(实参的定义就两种,位置参数和关键字参数)

            形参和实参是一一对应的关系,当实参的值不固定时,这时就需要形参提供方法来接收实参多余的值

  1.可变长度的位置参数

   实现形参接收实参多余的值:在定义参数时,在形参名前面添加*号,用来接收实参中多余的值,已元组的形式保存下来赋值给形参

      使用方式一:形参中使用*号,接收溢出的位置实参,以元组的形式保存下来赋值给形参

     def fount(x,y,*args):  # 通常用*号来接收溢出的位置实参,形参名约定用args来表示(用其他的名字也没有错误)

        print(x,y,args)  # 打印结果为:1 2(3,4,5,6,7)

     # 这里调用是使用的是位置实参,1、2按照位置给想,y赋值,多余的位置实参4、5、6、7都被*接收,以元组的形式保存下来,赋值给args,即args=(4, 5, 6,7)

     fount(1,2,3,4,5,6,7)  

   使用方式二:实参中使用*号,传值给形参

     def fount(x,y,*args):

        print(x,y,args)  # 输出结果为:1 2 (3,4,5,6) ;当调用函数是不加*,则输出:1 2 ([3,4,5,6]),就是普通的位置参数

     L=[3,4,5,6]     

     fount(1,2,*L)  # L相当于3 4 5 6,fount(1,2,*L)相当于fount(1,2,3,4,5,6),如果不添加*号,相当于把L当做值赋值给args,就是普通的位置参数

   使用方式三:形参为常规的参数(位置或默认),实参仍以*的形式实现

      def fount(x,y,z=3)

        print(x,y)  # 输出结果为:1 2 3

      L=[1,2]

      fount(*res)  # 等同于fount(1,2)

   使用方式四:*号的使用,当计算多个值的和

      def add(*args):

        res = 0

        for i in add:

          res += i

      add(1.2.3.4.5)

  2.可变长度的关键字参数

    关键字参数的长度可变:指在调用函数时,按照关键字进行传值调用,实参key = value不固定(关键字参数定义为key=value方式)

               形参中必须要有对应的值,当实参不固定时,这时就需要形参提供方法来接收溢出的关键字实参

    使用方式一:形参中使用**来接收多余的关键字实参,以字典的形式保存下来赋值形参名

       def fount(x,y,**kwargs):  # 用**号来接收溢出的关键字实参,形参名约定用kwargs(用其他的名字也没有错误)

          print(x,y,kwargs)  # 输出结果为:1 2 {'a': 3, 'b': 4}

       fount(y=2,x=1,a=3,b=4)  

       以上代码也可以用以下方式:

       def fount(x,y,**kwargs):

          print(x,y,kwargs)

       dic ={'x':1,'y':2,'a':3,'b':4}

       fount(**dic)  # 如果在调用函数时,传入的值没有加**号,这表示一个普通的位置参数了

    使用方式二:形参为常规参数(位置参数或默认参数),实参仍然可以用**的方式进行传值

       def fount(x,y,z=3)

         print(x,y,z)

      dic = {'y':2,'x':1}

      fount(**dic)  # 相当于fount(y=2,x=1)

    如果我们要编写一个用户认证的函数,起初可能只基于用户名密码的验证就可以了,可以使用**kwargs为日后的扩展供良好的环境,同时保持了函数的简洁性。

      def fount(name,pwd,**kwargs):

        pass

      fount(值)

  3.组合使用:参数可以任何组合,但是必须要有顺序

    组合使用顺序:位置参数--默认参数--*args--命名关键字参数--**kwargs

    通常可变参数*args和**kwargs组合在一起使用,那么代表函数可以接受任意形式、任意长度的参数

      def fount(*args,**kwargs):

        pass

    在该函数内部还可以把接收到的参数传给另外一个函数

      >>> def func(x,y,z):
      ...     print(x,y,z)
      ... 
      >>> def wrapper(*args,**kwargs):
      ...     func(*args,**kwargs)
      ...
      >>> wrapper(1,z=3,y=2)
      1 2 3

    按照上述写法,在为函数wrapper传参时,其实遵循的是函数func的参数规则,调用函数wrapper的过程分析如下:    

    1. 位置实参1被接收,以元组的形式保存下来,赋值给args,即args=(1,),关键字实参z=3,y=2被*接收,以字典的形式保存下来,赋值给kwargs,即kwargs={'y': 2, 'z': 3}
    2. 执行func(args,kwargs),即func((1,),* {'y': 2, 'z': 3}),等同于func(1,z=3,y=2)

 五、命名关键字参数

  1.命名关键字参数方式:在定义函数阶段,*后定义的参数称之为关键字形参

    举例:def func(x,y,*,a,b):  # * 后的参数为关键字形参,在调用阶段传值时,必须以关键字实参进行传值

        print(x,y,a,b)

       func(1,2,b=4,a=3)  # 在定义阶段时,a和b在* 之后,表示a和b为关键字形参,这里调用传值的时候也必须以关键字实参的格式进行传值

  2.命名关键字参数的特点

    在定义函数时,如果定义为关键字参数,那么在调用参数时,必须以关键字参数的方式传值,即key=value的方式传值

    

posted @ 2021-01-15 01:23  A熙  阅读(1223)  评论(0)    收藏  举报