• 函数之形参与实参


    一、形参和实参

    1、形参:在函数定义()中出现的参数形参就是拷贝实参的值,随着函数的调用才产生,随着函数调用结束而销毁

    def fn(a, b, c):
        print(a)
        print(b)
        print(c)
        print(x)
        print(y)
        print(z)
    
    x = 100
    y = 1000
    z = 10000          # x, y ,z 是外界实际存在的值

    2、实参:在函数调用()中出现的参数(外界实际存在的值)

    调用函数时,实参可以有常量,变量,表达式或三种组合。

    在函数的外部不能直接使用函数的形参,原因:函数调用完毕后,形参被销毁了

    fn(10, 20, 30)
    fn(x, y, z)
    fn(x + 10, y * 2, z / 5)

    二、实参的分类

    1、位置实参:不用明确形参名的传参方式,一定按照位置给形参传值

    def fn1(a, b, c):
        print(a, b, c)
    
    fn1(10, 20, 30)       # 必须按照顺序

    2、关键字实参:必须明确形参名与值为形参传值,可以不用按照位置

    def fn1(a, b, c):
        print(a, b, c)
    
    fn1(a=10, b=20, c=30)
    fn1(c=30, b=20, a=10)         # 可以不用按照顺序

    3、位置实参和关键字实参两者混用:

    关键字实参必须出现在位置实参后

    多个位置实参还是按照位置传参

    关键字实参为没有从位置实参拿到值的形参传值,可以不用按照指定顺序

    def fn2(a, b, c, d, e, f):
        print(a, b, c, d, e, f)
    
    fn2(10, 20, 30, e=100, f=500, d=200)   # 结果为 10 20 30 200 100 500
    
    
    fn1(10, c=20, a=30)  # 10按位置传参给a,a=30给a传参,c可以拿到20,但b没人传参
    # TypeError:fn1() got multiple values for argument 'a' a被多次传值

    三、位置形参的范畴

    1、位置形参:可以由‘位置实参’与‘关键字实参’来传值

    def fn(a, b, c):
        print(a, b, c)
    
    fn(10, 20, 30)              # 结果为10 20 30
    fn(a=10, b=20, c=30)        # 结果为10 20 30

    2、默认形参:可以由‘位置实参’与‘关键字实参’来传值,还可以不用传值(采用自身默认值)

    def fn(a=10, b=20,):
        print(a, b,)
    
    
    fn(20, 30)         # 位置实参
    fn(a=200, b=300)   # 关键字实参
    fn(100)            # 没传值
    fn(b=100)
    
    
    # 位置形参与默认形参同时存在,默认形参必须在后
    def fn(a, b, d=1000, c=5000):
        print(a, b, c, d)
    fn(100, 200, d=1000)  # 位置形参必须传值,默认形参分情况传值 # 结果为 100 200 5000 1000

    3、可变长位置形参:只能由’位置实参’来传值(*****)

    可变长形参会以元组形式接收,位置形参与默认形参没有接收完的,所有传入的位置实参,用索引来取第几个

    def fn(a, b=500, *args):
        print(a, b)
        print(args)
    fn(1, 20, 100, 200)
    # 结果为
    1 20
    (100, 200)
    
    fn(100)
    # 结果为
    100 500
    ()

    4、可变长形参的整体赋值:

    def fn(*args):
        print(args)
    fn(1, 2, 3, 4, 5)      # 结果为 (1, 2, 3, 4, 5)
    
    a = 'ab'
    b = [1, 2]
    c = (1, 2)
    d = {1, 2}
    fn(a)        # 结果为 ('ab', )
    fn(b)        # 结果为 ([1, 2], )
    fn(c)        # 结果为 ((1, 2), )
    fn(d)        # 结果为 ({1, 2}, )
    
    # 问就拿a,b,c,d进行传值,如何得到 # ('a', 'b') # (1, 2) # 解答:通过 打散传值(本质传递的是地址) fn(*a) # 结果为 ('a', 'b') fn(*b) # 结果为 (1, 2) fn(*c) # 结果为 (1, 2) fn(*d) # 结果为 (1, 2) # 打散传值 def fn(*args): print(args) ls = [1, 2, 3, 4, 5] fn(ls) # 结果为 ([1, 2, 3, 4, 5],) fn(*ls) # 结果为 (1,2,3,4,5) # 将ls打散为1,2,3,4,5再进行传值

    四、关键字形参的范畴

    1、关键字形参:必须由 '关键字实参'来传值, 出现在*后的都是关键字形参(*****)

    前提:出现在 * 之后的形参 。*为分割线,可以有变量名 *args, 也可以只用来做分隔

    def fn(a, b=10, *, c, d=20, e):
        pass
    
    a 位置形参
    b 默认形参
    c,e 无值关键字形参
    d 有值关键值形参
    注意:a和b有先后顺序,c,d,e无先后顺序
    c,d,e都是出现在*之后,都是关键字形参,
    由于必须由 关键字实参 来传值,没有顺序的强行要求
    def tt(a, b=10, *, c, d=10, e):
        print(a, b, c, d, e)
    
    
    def fn(*, a, b=10, c):
        print(a, b, c)
    fn(b=300, c=100, a=200)      # 结果为 200 300 100    # 没有顺序的强行要求

    2、可变长关键字形参:用来接收没有被‘关键字形参’接收完的关键字形参,也只能由关键字实参来传值

    用字典来存放数据{}

    def fn(*, a, b=20, c, **kwargs):
    print(a, b)
    print(kwargs)
    fn(d=40, e=50, a=10, c=30)
    # 结果为
    10 20
    {'d': 40, 'e': 50}

    3、可变长关键字形参的整体赋值:

    dic = {'name': 'Owen', 'age': 18}
    def fn1(**kwargs):
        print(kwargs)
    fn1(**dic)    # 结果为 {'name': 'Owen', 'age': 18}
    
    
    dd = {'k1': [1, 2, 3, 4, 5], 'k2': {"name":"Bob"}}
    fn1(**dd)      # 结果为 {'k1': [1, 2, 3, 4, 5], 'k2': {'name': 'Bob'}}
    
    
    def fn2(*args):
        print(args)
    ll = [1, [1, 2], {"name":"Bob"}]
    fn2(*ll)                   # 结果为 (1, [1, 2], {"name":"Bob"})

    五、参数总结

    1、位置形参与默认形参: 能用 位置实参 关键字实参 传值

    2、可变长位置形参:只能 位置实参 传值

    3、所以关键字形参:只能 关键字实参 传值

    def fn(a, b=10, *args, d, f=20, **kwargs):
        print(a)
        print(b)
        print(args)
        print(d)
        print(f)
        print(kwargs)
    
    有位置实参传值: args和kwargs如果都能接收到值:
          b必须传值且只能用位置实参传值,f可以不用传值
    fn(1,2,3,4,d=5,g=6,k=7)
    # 结果为
    

    1
    2
    (3, 4)
    5
    20
    {'g': 6, 'k': 7}

    
    全部用关键字实参传值
    fn(x=100, y=200, d=300, b=400, a=500)
    # 结果为

    500
    400
    ()
    300
    20
    {'y': 200, 'x': 100}

  • 相关阅读:
    Linux块设备IO子系统(二) _页高速缓存
    Linux块设备IO子系统(一) _驱动模型
    Linux usb子系统(二) _usb-skeleton.c精析
    Linux usb子系统(一) _写一个usb鼠标驱动
    Linux i2c子系统(四) _从i2c-s3c24xx.c看i2c控制器驱动的编写
    Linux i2c子系统(三) _解决probe无法执行
    Linux i2c子系统(二) _通过i2c-dev.c访问设备的方法
    Linux i2c子系统(一) _动手写一个i2c设备驱动
    从0移植uboot(六) _实现网络功能
    从0移植uboot(五) _实现串口输出
  • 原文地址:https://www.cnblogs.com/zhangguosheng1121/p/10623408.html
Copyright © 2020-2023  润新知