• day008|python之函数


    函数

    1 Type hinting

    # Type hinting
    def add(x: int, y: int) -> int:
        res = x + y
        return res
    
    print(add.__annotations__)
    # {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}
    

    2 函数参数

    2.1 概述

    • 函数参数可以分为两大类
      形参:在定义函数时,在括号内指定的参数/变量名,称之为形式参数,简称形参
      形参的本质就是变量名
      实参:在调用函数时,括号内传入的值,称之为实际参数,简称实参
      实参的本质就是变量值
    • 实参与形参的关系:在调用函数时,实参的值会绑定给形参,该绑定关系可以在函数内使用
      在函数调用结束后,会解除绑定关系

    2.2 参数详解

    • 位置形参
    位置形参: 在定义函数时,按照从左到右的顺序依次定义的变量名,称之为位置形参
          特点:必须被传值,多一个不行,少一个也不行
    def func(x, y):
        print(x, y)
    func(1, 2)
    func(1, 2, 3)       # 报错
    func(1)             # 报错
    
    • 位置实参
    位置实参:在调用函数时,按照从左到右的顺序依次传入的值,称之为位置实参
          特点:按照位置与形参一一对应
    def func(x, y):
        print(x, y)
    func(1, 2)
    func(2, 1)
    
    • 默认形参
    默认参数(具有默认值的形参):在定义函数时,就已经为某个形参赋值了,该形参就称之为默认参数
          特点:在调用阶段可以不用给默认形参传值
    def func(x, y=111):
        print(x, y)
    func(1, 2)          # 1 2
    func(1)             # 1 111
    
    def register(name, age, gender="male"):
        print(name, age, gender)
    register("egon", 18)
    register("lxx", 38)
    register("hxx", 32, "female")
    register("李建国", 30)
    register("alex", 31)
    register("xxx", 18)
    
    • 关键字实参
    关键字实参:在调用函数时,按照key=value的形式指定的实参,称之为关键字实参
          特点:可以打乱顺序,但仍能指名道姓为指定的形参赋值
    def func(x, y=2222):
        print(x, y)
    func(y=222, x=1212)         # 1212 222
    func(x=111)                 # 111 2222
    

    2.3 参数的使用

    • 实参的混用
    实参的混用:位置实参和关键字实参可以混用,但必须注意
      Ⅰ 位置实参必须放在关键字实参的前面
      Ⅱ 不能为同一个形参重复赋值
    def func(x, y=2222):
        print(x, y)
    func(1, y=2)              # 1 2
    func(y=2, 1)            # 报错
    func(1, y=2, x=3)       # 报错
    
    • 形参的混用
    形参的混用:位置形参和默认形参可以混用,但必须注意
      位置形参必须放在默认形参的前面
    def func(x, y=111):
        print(x, y)
    
    def func(y=111, x):     # 报错
        print(x, y)
    
    • 默认形参使用的注意点
    默认形参使用的注意点
       默认形参的值最好是不可变类型
    m = 222
    def func(x, y=m):
        print(x, y)
    m = 666
    func(111)               # 得到111 222
    
    def register(name,hobby,hobbies=[]):
        hobbies.append(hobby)
        print('%s 的爱好是 %s' %(name, hobbies))
    def register(name, hobby, hobbies=None):
        if hobbies is None:
            hobbies=[]
        hobbies.append(hobby)
        print('%s 的爱好是 %s' %(name, hobbies))
    register("egon", "smoke")
    register("lxx", "dance")
    register("hxx", "drink")
    

    2.4 可变长函数-->*与**的应用

    • 可变长指的是在调用函数时,传入参数个数不固定,而实参是为形参赋值的

    • 所以必须有对应格式的形参来接受溢出的实参

    • 用在形参中

    在形参中带*,*会将溢出位置实参汇总成元组,然后赋值给其后变量名,通常是args
    def func(x, y, *z):
        print(x, y, z)
    func(1, 2, 3, 4, 5)         # 1 2 (3, 4, 5)
    func(1, 2)                  # 1 2 ()
    func(1)                     # 报错
    
    def my_sum(*args):
        res = 0
        for i in args:
            res += i
        print(res)
    my_sum(1)               # 1
    my_sum(1, 2)            # 3
    my_sum(1, 2, 3)         # 6
    
    在形参中带**,**会将溢出关键字实参汇总成字典,然后赋值给其后变量名,通常是kwargs
    def func(x, y, **kwargs):
        print(x, y, kwargs)
    func(1, y=2, a=1, b=2, c=3)        # 1 2 {'a': 1, 'b': 2, 'c': 3}
    
    • 用在实参中
    在实参中带*:*会将紧跟其后的实参打散成位置实参,注意*后跟的应该是一个可以被for循环循环的类型
    def func(a, b, c, d):
        print(a, b, c, d)
    func(*"hello")                        # 报错,不对应
    func(*"hell")                           # h e l l
    func(*[11, 22, 33, 44])                 # 11 22 33 44
    func(11, 22, *[33, 44])                 # 11 22 33 44
    func(11, 22, *{"k1": 111, "k2": 222})   # 11 22 k1 k2
    
    在实参中带**:**会将紧跟其后的实参打散成关键字实参,注意*后跟的必须是一个字典
    def func(a, b, c, d):
        print(a, b, c, d)
    func(**{"k1": 333, "k2": 444})                              # 报错
    func(**{"d": 333, "b": 444, "a": 111, "c": 222})            # 111 444 222 333
    func(**[("d", 333), ("b", 444), ("a", 111), ("c", 222)])    # 报错
    
    • 混用
    混用
      Ⅰ 在形参中,*必须在**前
      Ⅱ 在实参中,*必须在**前
    def index(x, y, z):
        print('index------>', x, y, z)
    def wrapper(*arges, **kwargs):
        index(*arges, **kwargs)
    
    # wrapper(1, 2, 3, 4, a=1, b=2, c=3)      # 不能一一对应 报错
    wrapper(1, 2, 3)                # index------> 1 2 3
    wrapper(z=3, y=2, x=1)          # index------> 1 2 3
    
    
    def wrapper(*arges,**kwargs):
        print(arges)
        print(kwargs)
    
    wrapper(1, 2, a=1,b=2,c=3)      # (1, 2) {'a': 1, 'b': 2, 'c': 3}
    

    2.6 命名关键字形参

    • 在*与**之间定义的形参
    • 必须按照key=value的形式传值
    def func(x, y=1, *args, a=666, b, **kwargs):
        print(x)
        print(y)
        print(args)
        print(a)
        print(b)
        print(kwargs)
    func(1, 2, 3, 4, 5, 6, 7, a=111, b=222, c=333)      # 1 2 (3, 4, 5, 6, 7) 111 222 {'c': 333}
    func(1, 2, 3, 4, 5, 6, 7, b=222, c=333)             # 1 2 (3, 4, 5, 6, 7) 666 222 {'c': 333}
    func(1, 2, 3, 4, 5, 6, 7, b=222, 333)               # 报错
    

    3 函数对象

    • 函数是第一等公民(可以当变量使用)
    def func():
        print('from func')
    

    3.1 可以赋值

    f = func
    f()             # 输出from func
    

    3.2 可以当参数传给另一个函数

    def bar(x):
        print(x)
    mmm = 11111
    bar(mmm)           # 11111
    bar(func)          # <function func at 0x000002D4F29B63A0>
    

    3.3 可以当作一个函数的返回值

    def add(x):         # x=函数func的内存地址
        return x        # return 函数func的内存地址
    res = add(func)     # 相当于add(函数func的内存地址)
    print(res)          # <function func at 0x000002D4F29B63A0>
    

    3.4 可以当容器类型的元素

    x = 10
    l = [x, func]
    print(l)            # [10, <function func at 0x000002C48C4463A0>]
    l[-1]()             # from func
    
    # 练习
    # 新的功能只需要在字典中加入即可,无需动循环
    def login():
        print('login')
    def register():
        print('register')
    def transfer():
        print('transfer')
    def withdraw():
        print('withdraw')
    
    func_dic = {
        "1": [login, "登录"],
        "2": [register, "注册"],
        "3": [transfer, "转账"],
        "4": [withdraw, "提现"]
    }
    
    while True:
        print("0 退出")
        for k in func_dic:
            print(k, func_dic[k][-1])
        choice = input("请输入操作编号:").strip()
        if choice == "0":
            break
        if choice in func_dic:
            func_dic[choice][0]()
        else:
            print("输入的操作不存在")
    

    4 函数嵌套

    4.1 函数的嵌套定义

    def f1():
        print('from f1')
        def f2():
            print('from f2')
        print(f2)
        f2()
        x=1111
    f1()
    输出结果如下:
    # from f1
    # <function f1.<locals>.f2 at 0x00000274E0EB8700>
    # from f2
    
    from math import pi
    
    def circle(radius, mode=0):
        def perimiter(radius):
            return 2 * pi *radius
        def area(radius):
            return pi * (radius ** 2)
        if mode == 0:
            return perimiter(radius)
        elif mode == 1:
            return area(radius)
    res1 = circle(10, mode=0)
    print(res1)                 # 62.83185307179586
    res2 = circle(10, mode=1)
    print(res2)                 # 314.1592653589793
    

    4.2 函数的嵌套调用

    def max2(x, y):
        if x > y:
            return x
        else:
            return y
    
    
    def max4(a, b, c, d):
        res1 = max2(a, b)
        res2 = max2(res1, c)
        res3 = max2(res2, d)
        return res3
    
    
    res = max4(1, 2, 3, 4)
    print(res)              # 4
    
  • 相关阅读:
    中美贸易战再次开启,世界两极化进程正在加快形成!..... Copyright: 1688澳洲新闻网 Read more at: https://www.1688.com.au/world/international/2018/06/17/369368/
    缠师的博客中关于舒伯特中的回帖,细思极恐
    南怀瑾,脱了国学大师的外衣,只剩下江湖和名利
    你可能修了一个假的“不净观”
    陈大惠老师:什么叫道德?
    C#-正则,常用几种数据解析-端午快乐
    html5+go+websocket简单实例代码
    Task三个列子的分享
    golang-web框架revel一个表单提交的总结
    百度流行音乐-资源数据整合
  • 原文地址:https://www.cnblogs.com/caojiaxin/p/14045069.html
Copyright © 2020-2023  润新知