返回顶部

函数参数应用

一.形参和实参的介绍

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

# **形参名: 用来接受溢出的关键字参数, **会将溢出的关键字实参保存成字典格式, 然后赋值给后面的形参名, **后跟的可以用任何名字, 建议用kwargsdef 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 3def 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. 位置参数1被*接受, 以元组的形式保存下来, 赋值给args,即args=(1,), z=4 和y=2 被kwargs接受, 以字典的形式保存下来, 赋值给kwargs, 即kwargs={'z':3,'y':2}

    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]
posted @   fuju  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示

目录导航