• 函数的参数


    一:形参与实参

    基本概念:
      形参,形式参数,指的是定义函数时,括号内定义的参数,是某种意义上的变量名。
      实参,实际参数,指的是调用函数时,括号内传入的值,是某种意义上的变量值。
    注意点:
      实参和形参的绑定关系只有在函数调用时才会生效,调用结束后解除绑定,释放空间。调用函数,就是把实参赋值给形参的过程。

    二:位置参数

      位置即顺序,指的是从左到右的顺序依次定义的参数

    2.1:位置形参

    位置形参的特性:调用时必须为其传值,而且传入的值必须一个不多,一个不少。

    # 定义函数时,按照位置顺序定义的形参 
    def foo(x,y,z): 
      print(x,y,z)
    foo(1,2) #程序报错 
    foo(1,2,3,4)#程序报错 
    foo(1,2,3) #程序运行正常

    2.2:位置实参

    调用函数时,按照位置顺序定义传入的值
    位置实参特性:位置实参必须与形参一一对应

    3.关键字参数

    在调用函数时,以key=value形式定义的实参,称为关键字实参,相当于指名道姓的为形参传值,即便是不按照顺序定义,仍然能为指定形参传值

    def foo(x,y,z):
        print(x,y,z)
    foo(x=1,y=2,z=3) 
    foo(x=1,z=2,y=3)
    foo(z=3,x=2,y=1)
    #在以关键字参数为位置形参传值时,只要按照key=value的形式,就可以不用按照顺序

    4.混合参数

    在调用函数时,传入的实参同时有位置实参和关键字实参:

      位置实参必须放到关键字实参的前面。

      必须遵循形参的规则。

      不能为同一个形参重复传值

    def foo(x, y, z):
        print(x, y, z)
    
    foo(1, 2, z=3) 
    foo(x=1, 2, 3) 
    foo(1, 2, y=3)  
    foo(1, 2, z=3)
    foo(x=1, y=2, z=3)  
    foo(1, x=2, y=3, z=4) 

    5.默认参数

    在定义阶段已经为某个形参赋值,那么该形参就被称为默认参数。可以传值也可以不传值,经常需要变的参数定义成位置形参,变化较小的参数定义成默认参数

    1:默认参数已有值,,可以传值也可以不用传值

    def resgister(name, age, sex="male"):
        print(name, age, sex)
    
    resgister("egon", 18)
    resgister("alex", 73, "female")
    resgister("wxx", 45)

    2:位置形参必须在默认参数的前面;

    def resgister(sex="male", name, age):
        print(name, age, sex)
    
    resgister("alex", 73, "female")  # 程序报错

    3:默认参数的值,只在定义阶段赋值一次,也就是说在定义阶段默认参数已经写死了

    def resgister(name, age, sex="male"):
        print(name, age, sex)
    
    resgister("alex", 73, "female")  # 程序正常
    
    #由程序输出判断y的值由何而来
    m = 10
    def foo(x, y=m):
        print(x, y)
    
    m = 100
    foo(1)

    4:默认参数的值应该设置成不可变类型

      默认参数的值是可变类型

    def resgister(name, hobby, l=[]):
        l.append(hobby)
        print(name, hobby, l)
    
    
    # 错误实例
    resgister("egon", "play")  # egon play ['play']
    resgister("alex", "read")  # alex read ['play', 'read']
    resgister("wxx", "sleep")  # wxx sleep ['play', 'read', 'sleep']
    
    # 正确实例
    resgister("egon", "play", [])  # egon play ['play']
    resgister("alex", "read", [])  # alex read ['read']
    resgister("wxx", "sleep", [])  # wxx sleep ['sleep']

    把默认参数的值设置成不可变类型

    def resgister(name, hobby, l=None):
        if l is None:
            l = []
        l.append(hobby)
        print(name, hobby, l)
    
    
    resgister("egon", "play")  # egon play ['play']
    resgister("alex", "read")  # alex read ['read']
    resgister("wxx", "sleep")  # wxx sleep ['sleep']

    对于经常需要变化的值,需要将对应的形参定义错位置形参,对于大多数情况值都一样的情况,需要将对应的形参定义成默认形参。

    6.可变长参数

    可变长指的是实参的个数不确定,而实参有按位置的位置实参和按关键字的关键字实参两种形式,针对这两种形式的可变长,形参对于有两种解决方案来完整的存放他们分别是*args和**kwargs:

      *args:可变长度的位置形参(* 会将溢出的位置实参全部接收,然后保存成元组形式,赋值给args)

      *kwargs:可变长度的关键字形参(** 会将溢出的关键字参数全部接收,然后保存成字典形式,赋值给kwargs)

    *args和*kwargs主要的功能都是有*和**完成,后面的argshe kwargs都只是变量名,是什么并不重要,但是约定俗成,也就如此了。

    *args是可变长的位置形参,所以也具有位置形参的一切特性,*后定义的参数必须被传值(默认参数除外),切必须以关键字形式传值。

    def foo(x, y, *args, a=1, b, **kwargs):
        print(x, y)
        print(args)
        print(a)
        print(b)
        print(kwargs)

    7.在实参中的*和**

    形参中的 * 和 ** 把溢出的位置实参和关键字实参分别存成了元组和字典,那么在实参中*和**又是有什么功能呢?

    实参加*,就把该实参的值打散成字符串

    def foo(x,y,z):
        print(x,y,z)
    foo(*[1,2,3])
    #foo(*[123]) == foo(1,2,3)

    实参加**,就把该实参的值打散成关键字参数

    def foo(x,y,z,**kwargs):
        print(x,y,z)
        print(kwargs)
    foo(1,2,3,**{"a":4,"b":5})
    #foo(1,2,3,**{"a":4,"b":5}) == foo(1,2,3,a=4,b=5)

    打散的关键字实参和位置实参重复

    def foo(x,y,z,**kwargs): 
      print(x,y,z) 
      print(kwargs) 
    foo(1,2,3,**{"x":4,"b":5}) 
    #TypeError: foo() got multiple values for argument 'x'
    Ideal are like the stars --- we never reach them ,but like mariners , we chart our course by them
  • 相关阅读:
    解决IE新开窗口无法显示内容的问题
    日历控件
    关于索引,我们可以知道的更多 全表扫描和索引扫描
    C#构造函数的小说明
    动态创建的组件的ID设定
    正则表达式使用详解
    “运行”命令全集
    数组型参数
    接口实现的继承机制
    读取XML文件
  • 原文地址:https://www.cnblogs.com/li1992/p/8657739.html
Copyright © 2020-2023  润新知