函数参数应用
1.1形参: 在定义函数阶段定义的参数称为形式参数, 简称形参, 相当于变量名
def func(x, y): # x=1,y=2 形参
print(x, y)
1.2实参:在调用函数阶段传入的值称之为实际参数,简称形参, 相当于变量值
# 实参是常量
result = func(1, 2)
# 实参是变量
a = 1
b = 2
result = func(a, b)
# 实参是表达式
result = func(10*2, 10*func(1, 2))
# 实参可以是常量, 变量, 表达式的任意组合
a = 2
func(1,a,10*func(1,2))
-
在调用有参数函数时, 实参会赋值给形参(变量名). 在python中, 变量名与值只是单纯的绑定的关系,而对于函数来说, 这种绑定关系只在函数调用时生效, 在调用后结束
二. 形参和实参的使用
2.1 位置参数(位置形参)
-
位置参数指的是按顺序定义的参数, 分为两个角度:
-
在定义函数时: 按照从左到右的顺序一次定义形参, 为位置参数(必须传值)
def func(x, y): print(x, y) func(1, 2, 3) func(1, ) # 必须传值
-
2.2 位置实参
-
在函数调用阶段, 按照从左到右的顺序传入的值
-
按照顺序与形参一一对应
# func(1,2)
# func(2,1)
2.3 关键字参数
-
在函数调用阶段, 按照key=value形式传入值
-
可以完全不按照顺序
# def func(x,y):
# print(x,y)
# func(y=2,x=1)
>>> register(sex='male',name='lili',age=18)
Name:lili Age:18 Sex:male
-
实参也可以按照 位置或者按关键字的混合使用,必须保证关键字参数在位置参数后面,而且不可以对一个形参重复赋值
def register(name, age, sex):
print(f'name:{name},age:{age},gender:{sex}')
register('lili', sex='male', age=18) # 正确使用
# register(name='lili',18,sex='male') # SyntaxError:关键字参数name=‘lili’在位置参数18之前
# register('lili',sex='male',age=18,name='jack') # TypeError:形参name被重复赋值
2.4 默认参数
-
在函数定义时, 就已经给形参赋值, 这种形参称为默认参数, 如果函数参数有多个, 可以将常用的设置成位置参数, 不常用的改变较少设置为默认参数
-
例如学生注册函数, 可以将性别设置为默认参数
def register(name, age, sex='male'): # 默认sex的值为male
print(f'name:{name}, age:{age}, gender:{sex}')
register('jack', 19)
# name:jack, age:19, gender:male
# sex在函数定义时已经赋值, 可以不给传值, 不传,用默认的,根据实际情况传,
-
默认参数必须在位置参数后面
-
默认参数的值是在函数定义阶段被赋值的,准确地说被赋予的是值的内存地址
# m = 2
# def func(x, y=m): # y=>2的内存地址
# print(x, y)
#
#
# m = 1222
# func(1)
# 结果: 1,2
list1 = [111,]
def func(x, y=list1): # y=>list1的内存地址
print(x, y)
list1.append(222)
list1.append(333)
func(1)
#结果: 1 [111, 222, 333]
-
默认值参数虽然可以设置成任意数据类型, 建议不要设置为可变数据类型
-
函数的调用只和函数本身有关系, 不受外界代码的影响
2.5 可变长度的参数(* 和 **)
-
参数的长度可变指的是在调用函数时, 实参的个数不固定
2.5.1 可变长度的位置参数
-
-
形参名:用来接收溢出的位置实参,溢出的位置实参会被*保存成元组的格式然后赋值紧跟其后的形参名 *后跟的可以是任意名字,但是约定俗成应该是args
-
# def func(x,y,*args): # z =(3,4,5,6)保存成元组
# print(x,y,z)
# func(1,2,3,4,5,6)
def my_sum(*args):
result = 0
for item in args:
result += item # for循环元组 对传进来的值进行累加
return result
res = my_sum(1, 2, 3, 4)
print(res)
# 结果是 10
# * 也可以用在实参中, 实参中带*, *后的值打散成位置参数
def func(x, y, z):
print(x, y, z)
func(*(11,22), *{'k1':'111'})
# 结果: 11 22 k1
# 形参和实参中都带*
def func(x, y, *args):
print(x, y, args)
func(*[11,22,33,44], 12, 14)
# 结果:11 22 (33, 44, 12, 14)
2.5.2 可变长度的关键字参数
-
两个*形参名:用来接收溢出的关键字实参,会将溢出的关键字实参保存成字典格式,然后赋值给紧跟其后的形参名 **后跟的可以是任意名字,但是约定俗成应该是kwargs
# **形参名: 用来接受溢出的关键字参数, **会将溢出的关键字实参保存成字典格式, 然后赋值给后面的形参名, **后跟的可以用任何名字, 建议用kwargs
def func(x, y, **kwargs):
print(x, y, kwargs)
func(1, 2, a=1, b=2, c=4)
# 结果:1 2 {'a': 1, 'b': 2, 'c': 4}
# **可以用在实参中(**后跟的只能是字典), 实参中带**, **后的值打散成关键字参数
def func(x, y, z):
print(x, y, z)
# func(*{'a':1,'b':2,'c':3}) # *后面如果是字典, 传入的值就是字典的key a b c
func(**{'x':1,'y':2,'z':3}) # **后面如果是字典, 传入的就是值 1 2 3
def func(x, y, **kwargs):
print(x, y, kwargs)
func(**{'y':111, 'x':222, 'a':333, 'b':444})
# 222 111 {'a': 333, 'b': 444}
# 混用*和**: *args必须在**kwargs前面
def func(x, *args, **kwargs):
print(x, args, kwargs)
func(1,2,3,4,5,y=2,z=3)
2.6 命名关键字参数( 仅限关键字参数 )
-
在定义函数时, *后面的参数
-
特点: 命名关键字参数必须按照key=value形式为其传值
def func(x,y, *args,a,b): # a和b称之为命名关键字参数
print(x,y)
print(a, b)
func(1,2, 22,33, a=44,b=55)
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没有为命名关键字参数height传值。
-
命名关键字参数也可以有默认值, 从而简化调用
def register(name,age,*,sex='male',height): # sex,height为命名关键字参数
print(f'name:{name},age:{age},{sex},height:{height}')
register('lili',18,height='1.8m')
# name:lili,age:18,male,height:1.8m
注意: 这里sex不是默认值参数, height也不是位置参数, 因为二者都在 * 后面, 所以都是命名关键字参数,如果形参中已经有args了, 命名关键字参数就不需要一个单独的 * 作为分隔了
def register(name,age,*args,sex='male',height): # sex,height依旧为命名关键字参数
print(f'name:{name},age:{age},{sex},height:{height}')
register('lili',18,height='1.8m') # 正确使用
# name:lili,age:18,male,height:1.8m
2.7 参数的混合使用
-
参数的顺序: 位置参数丶*args丶默认值参数,丶命名关键字参数丶**kwargs
在该函数内部可以把接受到的参数传递给另外一个参数
def func(x, y, z):
print('func=>>> ', x, y, z)
def wrapper(*args, **kwargs): # args=(1,) kwargs={'z':3,'y':2}
func(*args, **kwargs)
# func(*(1,), **{'z':3,'y':2})
# func(1, z=3, y=2
wrapper(1, z=4, y=2) # 为wrapper传递的参数是给func的
在上面程序中, 在为函数wrapper传参时, 起始遵循的是函数func的参数规则, 调用函数wrapper分享:
-
-
位置参数1被*接受, 以元组的形式保存下来, 赋值给args,即args=(1,), z=4 和y=2 被kwargs接受, 以字典的形式保存下来, 赋值给kwargs, 即kwargs={'z':3,'y':2}
-
执行func(*args,**kwargs) 即func( * (1,), * *{'z':3,'y':2} ) 等同于func((1, z=4, y=2))
-
动态参数灵活运用
a, b = (1, 2)
print(a, b) # 1 2
# 其实还可以这么用:
a, *b = (1, 2, 3, 4,)
print(a, b) # 1 [2, 3, 4]
*rest, a, b = range(5)
print(rest, a, b) # [0, 1, 2] 3 4
print([1, 2, *[3, 4, 5]]) # [1, 2, 3, 4, 5]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY