python 函数的参数

一、形参与实参介绍

  • 函数的参数分为形式参数和实际参数:简称形参和实参
    • 定义函数阶段依次填写的参数名字,称为:形式参数(也称为形参)作为函数的输入,以便在函数内部进行处理。
    • 而在调用函数阶段,函数名括号中需要传入具体的值作为实际参数(也称为实参),这些实参会被赋值给函数中的形参,并作为函数的输入。
  • 在调用有参函数时:实参(值)会赋值给形参(变量名)。
  • 实参对于函数来说:实参与形参的这种绑定关系只在函数调用时生效,在调用结束后解除。
  • 形参和实参的关系:
    • 形参可以看成是变量名,实参可以看成是变量值
    • 他们两个在函数调用阶段临时绑定关系,形参=实参
  • 形参只有一种形式:那就是变量名
  • 实参有很多种形式:但是本质都是变量值,直接通过数据值传递、通过变量名间接传递、还可以是函数的返回值等各种形式
1. def add(a, b):#	在定义阶段时,写在函数名括号里的称为:形参  用来接收外部传来的值
    return a + b
""" a 和 b 是函数的形参,它们可以被看做是函数内部的变量名。当我们调用该函数时,必须传入两个具体的整数值"""

2. result = add(3, 5)#在调用阶段,函数名后面括号中的参数称为实参	值可以是常量、变量、表达式或三者的组合
	print(result)  # 输出 8 
""" 3 和 5 是函数 add() 的实参。当函数被调用时,这两个实参分别被赋值给 a 和 b,并且计算它们的和。最后,函数 add() 返回计算结果 8,并被赋值给变量 result,随后被输出。"""

3.实参是常量
res=my_min(1,2)

4.实参是变量
a=1
b=2
res=my_min(a,b)

5.实参是表达式
res=my_min(10*2,10*my_min(3,4))

6.实参可以是常量、变量、表达式的任意组合
a=2
my_min(1,a,10*my_min(3,4))

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

1. 位置参数

  • 位置也就是顺序,位置参数是指按照函数定义中的顺序依次传入的实参,也就是第一个形参对饮第一个实参以此类推。。。
    • 在定义函数时,按照从左到右的顺序依次定义形参,称为:位置形参,凡是按照这种形式定义的形参都必须传实参
    • 在调用函数时,按照从左到右的顺序依次定义实参,称为位置实参,凡是按照这种形式定义的实参会按照从左到右的顺序与形参一一对应
def add(a, b):
    return a + b

result = add(3, 5)   # 位置参数 3 和 5 按照位置顺序传入
print(result)        # 输出 8
add() #函数接受两个位置参数 a 和 b,并按照从左到右的顺序进行传递。在调用 add() 函数时,传入的实参为 3 和 5,这两个实参分别被赋值给形参 a 和 b,并且计算它们的和。

2. 关键字参数

  • 关键字参数:就是在调用阶段,通过形参名指定一个实参
  • 实参是key=value的形式,称为关键字参数,就是定义好形参名字之后,在实参那里通过 " 形参名 = 指定的实参 " 不需要按照左右顺序传递,指定实参是啥,他就是啥
  • 调用函数时,实参可以是按位置或者按关键字给形参赋值,但是必须保证关键字参数在位置参数后面,而且同一个形参不可以重复赋值,会报错
  • 当位置参数和关键字参数都同时存在的情况,位置参数一定要写在关键字参数的前面(越简单的越靠前)
def add(a, b):
    return a + b

result = add(b=5, a=3)   # 关键字参数以形参名=实参的方式进行传递
print(result)            # 输出 8

调用 add() 函数时,通过形参名显式指定了实参 a=3 和 b=5,这两个实参并不按照函数定义中的顺序进行传递。在函数内部,这两个实参分别被赋值给形参 a 和 b,并且计算它们的和。

3. 默认参数

  • 默认参数:就是在定义阶段,就可以给函数的形参提前赋值 x
  • 定义好了默认参数,可以不用传实参,若是传了实参,会把默认参数按照位置顺序替换成你传的实参
    • 如果你没有传递对应的实参,那就使用你的默认值
    • 如果你传递了对应的实参,那就使用你传递的参数值
  • 在定义默认参数的时候,默认参数不能放在位置参数的前面(越简单的越靠前)
  • 默认参数的值仅在函数定义阶段被赋值一次,后面就无法改变了
  • 默认参数的值通常应设为不可变类型 ,每次调用是在上一次的基础上向同一列表增加值
def add(a, b=0):   # 形参 b 默认值为 0
    return a + b

result1 = add(3)    # 未传递实参 b,使用默认值 0
result2 = add(3, 5) # 实参 3 和 b=5 按照位置顺序传递
print(result1)      # 输出 3
print(result2)      # 输出 8

定义了一个 add() 函数,并给形参 b 赋予默认值 0。当在调用 add() 函数时没有传递实参 b 时,会使用默认值 0。例如,result1 的计算结果为 3,而 result2 的计算结果为 8。


"""需要注意的是,在使用默认参数时,必须将默认参数定义在位置参数之后,否则会出现语法错误。"""
1.正确示例
def add(a, b=0):
    return a + b
2.错误示例,会产生语法错误
def add(b=0, a):
    return a + b

4. 不定长参数(*args与kwargs**的用法)

  • 在python中我们以后定义函数的时候,如果不指定函数需要的参数个数,我们就使用使用*号和**号代替
  • 什么是不定长参数:实参的个数可以不固定可以有很多,简单解释“在调用函数时,实参的定义无非是按位置或者按关键字两种形式,不定长就解决了一种形式可以直接传递不经常使用的形参”
  • Python 中提供了两种不定长参数,分别是 *args 和 **kwargs。默认是这样写,但是后面的不一定非要是 args 或 kwasgs,可以改的
  • 1.在形参中的使用:
    • 接收多余的位置参数,把多余的位置参数以元组的形式赋值给*号后面的变量名2.在实参中的使用:
    • 把列表、元素等可变类型的数据打散成位置参数一一传递,在形参中要使用*号接收

*args (不定长位置参数)

*args 用于接收任意数量的位置参数,在最后一个形参名前加 *args 那么在调用函数时,溢出的位置实参,都会被接收,以元组的形式保存下来赋值给该形参

1.循环求多个值的和
def add(*nums):
    result = 0      # 初始化计算结果为 0
    for num in nums:
        result += num
    return result

result1 = add(3, 5, 7)
result2 = add(2, 4, 6, 8, 10)

print(result1)  # 输出 15
print(result2)  # 输出 30

定义了一个 add() 函数,并使用 *nums 形参来接收任意数量的位置参数。在函数内部,可以通过循环遍历这些位置参数,并将它们累加到计算结果中。

2.正常接收溢出的实参
def foo(x,y,z=1,*args): #在最后一个形参名args前加*号
     print(x)
     print(y)
     print(z)
     print(args)
 
foo(1,2,3,4,5,6,7)  #实参1、2、3按位置为形参x、y、z赋值,多余的位置实参4、5、6、7都被*接收,以元组的形式保存下来,赋值给args,即args=(4, 5, 6,7)

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

3.使用列表传给*args
def foo(x,y,*args):
     print(x)
     print(y)
     print(args)
 
L=[3,4,5]
foo(1,2,*L) # *L就相当于位置参数3,4,5, foo(1,2,*L)就等同于foo(1,2,3,4,5)
1
2
(3, 4, 5)

4.如果在传入L时没有加*,那L就只是一个普通的位置参数了
foo(1,2,L) #仅多出一个位置实参L
1
2
([1, 2, 3],)

5.如果形参为常规的参数(位置或默认),实参仍可以是*的形式
def foo(x,y,z=3):
     print(x)
     print(y)
     print(z)

foo(*[1,2]) #等同于foo(1,2)
1
2
3

**kwargs (不定长关键字参数)

**kwargs 用于接收任意数量的关键字参数,如果在最后一个形参名前加 **kwargs ,那么在调用函数时,溢出的关键字参数,都会被接收,以字典的形式保存下来赋值给该形参

1.在形参中的使用:

接收多余的关键字参数,把多余的关键字参数以字典的形式赋值给**号后面的变量名2.在实参中的使用:

把字典等可变类型的数据打散成关键字参数一一传递,在形参中要使用**号接收

1.组装数据
def print_info(**info):
for key, value in info.items():
    print(f"{key}: {value}")

print_info(name="Alice", age=21)
print_info(username="bob", password="123456")

定义了一个 print_info() 函数,并使用 **info 形参来接收任意数量的关键字参数。在函数内部,可以通过遍历这些关键字参数,并打印其键值对。

2.正常接收实参给**kwargs 
def foo(x,**kwargs): #在最后一个参数kwargs前加**
     print(x)        
     print(kwargs)   
 
foo(y=2,x=1,z=3) #溢出的关键字实参y=2,z=3都被**接收,以字典的形式保存下来,赋值给kwargs
1
{'z': 3, 'y': 2}

3.生成了一个字典,仍然是可以传值给**kwargs
def foo(x,y,**kwargs):
     print(x)
     print(y)
     print(kwargs)
 
dic={'a':1,'b':2} 
foo(1,2,**dic) #**dic就相当于关键字参数a=1,b=2,foo(1,2,**dic)等同foo(1,2,a=1,b=2)
1
2
{'a': 1, 'b': 2}

4.如果在传入dic时没有加**,那dic就只是一个普通的位置参数了
foo(1,2,dic) #TypeError:函数foo只需要2个位置参数,但是传了3个

5.如果形参为常规参数(位置或默认),实参仍可以是**的形式
def foo(x,y,z=3):
     print(x)
     print(y)
     print(z)
 
foo(**{'x':1,'y':2}) #等同于foo(y=2,x=1)
1
2
3

5.  命名**kwargs (不定长关键字参数)

1.不使用命名关键字,就必须依赖 if 去判断
def register(name,age,**kwargs):
     if 'sex' in kwargs:
        #有sex参数
         pass
     if 'height' in kwargs:
         #有height参数
         pass
如果不是用命名关键字的话,而去使用**kwargs参数,函数调用阶段就可以传入任意的关键字参数key=value,但是代码的执行就需要依赖某个key,还必须在函数内进行判断

2.使用命名关键字
def register(name,age,*,sex,height): #sex,height为命名关键字参数
     pass
 
register('lili',18,sex='male',height='1.8m') #正确使用
register('lili',18,'male','1.8m') # TypeError:未使用关键字的形式为sex和height传值
register('lili',18,height='1.8m') # TypeError:没有为命名关键字参数sex传值。
如果想限制必须以key=value的形式传值,需要在先使用"*"星号作为分隔符,之后在函数调用时,必须按照key=value的形式为其传值,且必须被传值

3.命名关键字参数也可以有默认值,从而简化调用
def register(name,age,*,sex='male',height):
     print('Name:%s,Age:%s,Sex:%s,Height:%s' %(name,age,sex,height))
 
register('lili',18,height='1.8m')
运行结果:name:lili,Age:18,Sex:male,Height:1.8m
""" 
前调:sex 和 height 既不是默认参数也不是位置参数,所以都是命名关键字参数
如果形参中已经有一个args了,命名关键字参数就不再需要一个单独的*作为分隔符号了
"""

4.如果添加了 args 的话被使用掉了那么后面的参数也是命名关键字
def register(name,age,*args,sex='male',height):
   print('Name:%s,Age:%s,Args:%s,Sex:%s,Height:%s' %(name,age,args,sex,height))
 
register('lili',18,1,2,3,height='1.8m') #sex与height仍为命名关键字参数
执行结果Name:lili,Age:18,Args:(1, 2, 3),Sex:male,Height:1.8m

6. 所有参数可任意组合使用

  • 综上所述所有参数可任意组合使用,定义顺序必须是位置参数、默认参数、关键字、*args、命名关键字参数、**kwargs
  • 可变参数args与关键字参数kwargs通常是组合在一起使用的
  • 如果一个函数的形参为args与kwargs,那么代表该函数可以接收任何形式、任意长度的参数
  • *args、**kwargs中的args和kwargs被替换成其他名字并无语法错误,但使用args、kwargs是约定俗成的
def wrapper(*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

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)

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王献运

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值