B2_Python中函数的参数传递详解

常见的四种参数传递方式

1. 位置传参

  • 普通位置传参

    形参和实参按照对应的位置一一对应进行传参(使用最广泛)

  • 代码示例

    # 位置传参
    	def position_args_function(args1,args2,args3):
    	    print("args1: {}, args2: {}, args3: {}".format(args1,args2,args3))
    	
    	
    	args1,args2,args3 = [1,2,3]
    	position_args_function(args1,args2,args3)
    	args1,args2,args3 = ["a","b","c"]
    	position_args_function(args1,args2,args3)
    
  • 运行结果

    	args1: 1, args2: 2, args3: 3
    	args1: a, args2: b, args3: c
    
  • 序列传参

    配合*号表达式,可以解包一个序列,然后按照对应的位置进行位置传参

  • 代码示例

    # 序列位置传参
    def seq_position_args_function(args1,args2,args3):
        print("args1: {},args2: {},args3: {}".format(args1,args2,args3))
    
    # 使用序列解包传参的时候,如果函数定义的形式有参数的个数限制,则序列的元素个数必须和形参的
    # 位置参数个数相同
    lst = [1,2,3]
    seq_position_args_function(*lst)
    tup = (4,5,6)
    seq_position_args_function(*tup)
    st = {
          
          7,8,9} # 注意st是无序的,所以解包出来的时候,不一定是按照7,8,9进行解包的
    seq_position_args_function(*st)
    s = "def"
    seq_position_args_function(*s)
    rang = range(10,13)
    seq_position_args_function(*rang) # *号也可以解包迭代器
    
  • 运行结果

    args1: 1,args2: 2,args3: 3
    args1: 4,args2: 5,args3: 6
    args1: 8,args2: 9,args3: 7
    args1: d,args2: e,args3: f
    args1: 10,args2: 11,args3: 12
    

2. 关键字传参

  • 赋值表达式关键字传参

    1. 赋值表达式中变量的形参名称和实参名称必须一一对应
    2. 对于顺序没有要求,是按照名称进行传递的
  • 代码示例

    # 关键字传参,按照名字一一对应
    def keyword_args_function(args1, args2, args3):
        print("args1: {}, args2: {}, args3: {}".format(args1, args2, args3))
    
    # 关键字传参,对传参的顺序没有要求,会按照名字去一一对应
    keyword_args_function(args1=1, args2=2, args3=3)
    keyword_args_function(args3=3, args2=2, args1=1)
    keyword_args_function(args2=2, args3=3, args1=1)
    
  • 运行结果

    args1: 1, args2: 2, args3: 3
    args1: 1, args2: 2, args3: 3
    args1: 1, args2: 2, args3: 3
    
  • 字典传参(配合双星号)

    1. 字典的键名和形参的名必须一致,并且键名要在形参当中
    2. 字典的键名必须是字符串
  • 代码示例

    def dict_keyword_args_function(args1, args2, args3):
        print("args1; {}, args2: {}, args3: {}".format(args1, args2, args3))
    
    
    dtArgs1 = {
          
          "args1": 1, "args2": 2, "args3": 3}
    dict_keyword_args_function(**dtArgs1)
    
    dtArgs2 = dict(args1=1,args3=3,args2=2)
    dict_keyword_args_function(**dtArgs2)
    
    dtArgs3 = dict.fromkeys(["args1","args2","args3"],"defaultVal")
    dict_keyword_args_function(**dtArgs3)
    
  • 运行结果

    args1; 1, args2: 2, args3: 3
    args1; 1, args2: 2, args3: 3
    args1; defaultVal, args2: defaultVal, args3: defaultVal
    

3. 位置传参和关键字传参混合使用

  1. 函数的传参方式在形参能够唯一匹配到当前的实参的前提下可以混合使用
  2. 要求: 位置传参在前,关键字传参在后
  • 代码示例

    # 位置传参和关键字传参的混合使用
    def position_keyword_args_both_funcion(a,b,c,d):
        print("a: {}, b: {},c: {},d: {}".format(a,b,c,d))
    
    # 位置传参和关键字传参混合使用,关键字传参没有顺序要求,但是个数和名称必须对应上
    position_keyword_args_both_funcion("aa",c="cc",d="dd",b="bb")
    # 错误的示例: 关键字传参在前,位置传参在后的情况
    # position_keyword_args_both_funcion(a="aa",b="bb",c="cc","dd")
    
    # 位置传参和*号序列传参配合使用
    position_keyword_args_both_funcion("aa",*["bb","cc","dd"])
    
    # *号 和 ** 号同时使用
    position_keyword_args_both_funcion(*["aa","bb"],**{
          
          "d":"dd","c":"cc"})
    
    # *号和赋值表达值关键字传参混合使用
    position_keyword_args_both_funcion(*["aa","bb"], d= "dd",c = "cc")
    
    # *号 在前, 位置传参在后
    position_keyword_args_both_funcion(*["aa","bb"],"cc","dd")
    
  • 运行结果

    a: aa, b: bb,c: cc,d: dd
    a: aa, b: bb,c: cc,d: dd
    a: aa, b: bb,c: cc,d: dd
    a: aa, b: bb,c: cc,d: dd
    a: aa, b: bb,c: cc,d: dd
    

4. 函数的缺省参数

  1. def func(args1,args2=val1,args3=val2) 这种方式进行定义
  2. 调用的时候args2,args3可以不提供参数,系统会使用默认的参数来执行
  3. 缺省参数必须在位置参数的后面,并且从右到左依次存在.如果一个参数是缺省参数,
    则它的右边所有的参数都必须有缺省参数
  4. 缺省参数可以有1个或者多个,甚至全部都是缺省参数
  • 代码示例

    # 带缺省参数的函数
    def default_args_function(a, b=0, c=0, d=0):
        print("a: {}, b: {},c: {},d: {}".format(a, b, c, d))
    
    # 如果只提供一个参数,后面默认是2,3,4
    default_args_function(1)
    # 如果提供了两个参数,并且都是位置参数,会按照顺序赋值给缺省参数
    default_args_function(1,2)
    # 如果提供了两个参数,但是后面的参数,是命名关键字传参,则会根据名称进行赋值传参
    default_args_function(1,c=3)
    # 所有的缺省参数都进行传递
    default_args_function(1,2,3,4)
    
  • 运行结果

    a: 1, b: 0,c: 0,d: 0
    a: 1, b: 2,c: 0,d: 0
    a: 1, b: 0,c: 3,d: 0
    a: 1, b: 2,c: 3,d: 4
    

常见的函数形参定义格式

1. 位置形参,每个形参都有形参名

  1. def func(args1,args2,args3,args4) 这种格式
  2. 每个形参都有名称,传入实参的时候,可以位置传参,也可以关键字传参,但是形参和实参个数必须一致

2. 星号元组形参

  1. def func(*args)
  1. ***args**的作用和目的就是收集多余的位置传参
  2. args是一个元组,*****号还可以作为一个形参占位符来使用,目的是强制后面的参数必须是命名关键字传参
  • 代码示例

    def star_tuple_args_function(*args):
        print("args: {},type(args): {}".format(args,type(args)))
    
    star_tuple_args_function(1,2) # 两个参数
    star_tuple_args_function(1,2,3,4) # 4个参数
    star_tuple_args_function(1)# 1个参数
    star_tuple_args_function() # 无参数
    
    
    # *号进行占位,强制后面的参数必须是命名关键字传参
    def star_placeholder_args_function(a,*,b,c):
        print("a: {},b: {},c: {}".format(a,b,c))
    
    star_placeholder_args_function(1,b=2,c=3)
    star_placeholder_args_function(a=1,b=2,c=3)
    
  • 运行结果

    args: (1, 2),type(args): <class 'tuple'>
    args: (1, 2, 3, 4),type(args): <class 'tuple'>
    args: (1,),type(args): <class 'tuple'>
    args: (),type(args): <class 'tuple'>
    a: 1,b: 2,c: 3
    a: 1,b: 2,c: 3
    

3. 命名关键字形参

  1. def func(args1,*,args2,args3) or def func(args1=val1,args2=val2,args3=val3)
  2. 命名关键字形参可以在前面写一个*号进行占位,强制后面的参数必须使用关键字的传参方式
  • 代码示例

    # *args后面的参数必须是命名关键字传参的方式
    def func(a,b,*args,c,d):
        print("a: {},b:{},args:{},c:{},d:{}".format(a,b,args,c,d))
    
    # c,d必须是关键字传参,因为*args会接收多余的位置传参
    func(1,2,3,4,5,c="cc",d="dd")
    
    def func2(a,b,*,c,d):
        print("a: {},b:{},c:{},d:{}".format(a,b,c,d))
    
    # a,b可以是位置传参也可以是关键字传参
    func2(1,2,c="c",d="d")
    func2(a="a",b="b",c="c",d="d")
    # func2(1,2,3,4) # 错误,*号占位符后面的实参只能是命名关键字传参
    func2(1,2,**dict(c=3,d=4))
    
  • 运行结果

    a: 1,b:2,args:(3, 4, 5),c:cc,d:dd
    a: 1,b:2,c:c,d:d
    a: a,b:b,c:c,d:d
    a: 1,b:2,c:3,d:4
    

4. 双星号字典形参

  1. def func(**kwargs) kwargs的格式是字典
  2. 作用是手机多余的关键字传参
  3. 在位置传参的后面
  • 示例代码

    def fa(**kwargs):
        print("kwargs: {}, type(kwargs): {}".format(kwargs,type(kwargs)))
    
    # 字典双星号传参
    fa(a=1,b=2,c=3)
    # fa(1,2,3) # 错误,位置传参不接收
    fa(**{
          
          "a":1,"b":2,})
    # fa(**{1:"a",2:"b",3:"c"}) # 字典双信号解包传参的时候,注意键只能是字符串
    
  • 运行结果

    kwargs: {
          
          'a': 1, 'b': 2, 'c': 3}, type(kwargs): <class 'dict'>
    kwargs: {
          
          'a': 1, 'b': 2}, type(kwargs): <class 'dict'>
    

5. 各种参数传递的综合使用

  1. def func(a,b,c="cc",d="dd",*args,e,f,**kwargs)
  2. 参数顺序 位置传参 -> 默认缺省参数 -> 星号元组传参 -> 命名关键字传参 -> 双星号字典传参
  • 代码示例

    def myfunc(a,b,c="cc",d="dd",*args,e,f,**kwargs):
        print(a,b,c,d,args,e,f,kwargs)
    
    myfunc(1,2,"ccc","ddd",5,6,e=7,f=8,g="g",h="h")
    
  • 运行结果

    1 2 ccc ddd (5, 6) 7 8 {
          
          'g': 'g', 'h': 'h'}
    

Guess you like

Origin blog.csdn.net/Fioman_GYM/article/details/120533270