day10-函数进阶

总结

1. 函数参数
  • 位置参数和关键字参数

  • 根据实参的提供方式不同将实参分为位置参数和关键字参数

    1. 位置参数: 调用函数的时候让实参和形参在位置上一一对应
    2. 关键字参数:调用函数的时候以’形参名=值’的形式确定形参对应的实参
    3. 位置参数和关键字参数混用:位置参数必须在关键字参数前面, 同时必须保证每个参数都会有一次赋值
    def func1(x, y, z):
        print(f'x:{x},y:{y},z:{z}')
    # 位置参数
    func1(10, 20, 30)
    func1(10, 30, 20)
    # 关键字参数
    func1(x=10, y=20, z=30)
    func1(z=30, x=10, y=20)
    # 混用
    func1(10, y=20, z=30)
    func1(10, 20, z=30)
    
  • 参数默认值

    1. 定义函数的时候可以直接在形参后面用=给形参赋默认值
    2. 有有默认值的参数在调用的时候可以不用传参(也可以传参,不传参就用默认值)
    3. 如果有的参数有默认值,有的没有,有默认值的参数必须放在没有默认值参数的后面
    def func2(x=100, y=200, z=300):
        print(f'x:{x},y:{y},z:{z}')
    
    func2()   # x:100,y:200,z:300
    func2(1000)  # x:1000,y:200,z:300
    func2(z=3000) # x:100,y:200,z:3000
    func2(x=1000, z=3000)  # x:1000,y:200,z:3000
    
  • 参数类型说明

    1. 无默认值参数的类型说明 - :类型名

    2. 有默认值的参数, 默认值的类型就是参数的对应类型

  • 不定长参数

    1. 带*的不定长参数:在某个形参前加*,那么这个形参就是一个不定长参数, 它可以接受任意多个实参, 带*的参数本质就是一个元组,对应的实参是元组中的元素

      注意: *的不定长参数对应的实参必须用位置数据传参

    2. 带*的不定长参数:在某个形参前加*, 那么这个形参就是一个不定长参数, 它可以接受任意多个参数, 带**的参数本质就是一个字典, 对应的关键字参数就是字典中的键值对

      注意: **的不定长参数对应的实参必须使用关键字参数传参

    def func5(*x):
        print(x)
    
    func5()
    func5(10)
    func5(10, 20)
    func5(1, 2, 3, 4, 5)
    
    1. 定长参数在*的不定长参数前, 定长和不定长都使用位置参数传参
    def func6(char, x, *nums):
        print(f'char:{char}, nums:{nums}, x:{x}')
    
    func6('+', 10)
    func6('-', 12, 34, 45)
    
    1. 定长在*的不定长参数后,*后面的定长参数必须使用关键字参数传参
    def func7(*nums, char):
        print(f'nums:{nums}, char:{char}')
    
    func7(10, 20, char='*')
    
    def func8(*, a, b, c):
        print(f'a:{a}, b:{b}, c:{c}')
    
    func8(a=10, b=20, c=30)
    
    1. **的使用
    def func9(**x):
        print(x)
    func9()   # {}
    func9(x=10)    # {'x': 10}
    func9(a=10, b=20)    # {'a': 10, 'b': 20}
    func9(m=1, n=2, a=3, b=4)    # {'m': 1, 'n': 2, 'a': 3, 'b': 4}
    
    1. 定长参数在**的不定长前, 定长既可以用位置参数也可以用关键字参数
    def func10(x, **y):
        print(f'x:{x}, y:{y}')
    func10(10, a=10, b=20)   # x:10, y:{'a': 10, 'b': 20}
    func10(x=100, m=1, n=2)  # x:100, y:{'m': 1, 'n': 2}
    
    1. 定长参数不能放在**对应不定长参数后面
    2. 带*的不定长参数和带**的不定长参数可以一起用, 带*的必须放在带**的前面
    def func11(*args, **kwargs):
        print(args, kwargs)
    
    func11()
    func11(10)
    func11(10, 29, 9)
    func11(a=2)
    func11(a=10, b=20)
    func11(1, 20, a=10)
    
2.函数返回值
  • 返回值

    返回值的作用就是将函数内部的数据传递到函数外部

  • 怎么确定函数返回值

    在函数体中用return关键字来返回返回值(一个函数只有一个返回值)

    什么时候需要返回值:如果函数的功能产生了新的数据, 将新的数据返回

  • 怎么获取函数返回值

    获取函数调用表达式的值就是获取函数返回值

    函数调用表达式 - 调用函数的语句

    函数调用表达式的值就是函数的返回值,函数返回值能做的事情,函数调用表达式都可以做

    a = 10
    dict1 = {'a':100, 'b':func1()}
    print(dict1)  # {'a': 100, 'b': 100}
    
    def func2():
        return [10, 20]
    print([10, 20][-1])  # 20
    print(func2()[-1])   # 20
    list1 = [100, 200]
    list2 = func2()
    list1.append(300)
    list2.append(300)
    print(list1, list2)  # [100, 200, 300]  [10, 20, 300]
    
  • 函数调用过程

    第一步: 回到函数定义的位置

    第二步:传参(用实参给形参赋值, 这个时候要保证每个参数都有值)

    第三步:执行函数体

    第四步:执行完函数体的时候确定函数返回值

    (看执行函数体的时候有没有遇到return,如果遇到return, return后面的值什么,函数的返回值就是什么,并且在遇到return的时候函数直接结束.如果没有遇到return,函数的返回值是None)

    第五步:回到函数调用位置,接着往后执行(这个时候函数调用表达式的值才是函数的返回值)

    def func3():
        print('====')
        return
        print('++++')
    print(func3())  # None
    # python的函数只有一个返回值
    def func4():
        return 10, 20
    print(func4())  # 返回元组(10, 20)
    

    练习: 写一个函数通过指定方式来计算多个数的结果

    operation(’+’, 10, 20, 30) -> 求: 10+20+30
    operation(’’, 3, 4, 5, 6) -> 求 3456
    operation(’-’, 10, 3, 4) -> 求: 10-3-4
    operation(’/’, 19, 2) -> 求 19/2

    def operation(operator: str, *nums):
        if not nums or operator not in ('+', '-', '*', '/'):
            return None
    
        if operator == '+':
            sum1 = 0
            for x in nums:
                sum1 += x
            return sum1
    
        if operator == '*':
            sum1 = 1
            for x in nums:
                sum1 *= x
            return sum1
    
        if operator == '-':
            sum1 = nums[0]
            for x in nums[1:]:
                sum1 -= x
            return sum1
    
        if operator == '/':
            sum1 = nums[0]
            for x in nums[1:]:
                sum1 /= x
            return sum1
    
    print(operation('+', 10, 20, 30))
    print(operation('*', 3, 4, 5, 6))
    print(operation('-', 10, 3, 4))
    print(operation('/', 19, 2))
    
3.变量的作用域
  • 变量的作用域 - 已经定义过的变量能使用范围

    根据变量的作用域不同,将变量分为全局变量和局部变量两种

  • 全局变量

    没有定义在函数里面或者类里面的变量就是全局变量

    全局变量的作用域:从定义开始到程序结束的任何位置都可以使用

    # a, b和x都是全局变量
    a = 10
    for x in range(5):
        b = 20
    print('循环外面:', x)
    def func1():
        print(f'函数里面a:{a}, b:{b}, x:{x}')
    func1()
    
  • 局部变量

    定义在函数里面的变量就是局部变量(形参也是局部变量)

    局部变量的作用域:从定义开始到函数结束

    # c和d都是局部变量
    def func2(c=3):
        d = 100
        print(f'函数内部c:{c}, d:{d}')
    
    func2()
    # print(f'函数外部c:{c}, d:{d}')  报错
    
  • 函数调用过程就是压栈的过程

    调用函数的时候,系统会自动在栈区间为这个函数创建一个临时栈区间,用来保存在函数中产生的数据(局部变量),当函数调用结束,这个临时栈区间会自动释放(释放之前会将返回值传递到临时栈区间的外部)

  • global

    在函数中修改一个全局变量的值或者在函数定义一个全变量

    global 变量名

    使用变量名

    num = 30
    def func3():
        num = 40  # 不是在修改全局变量num的值,而是定义一个新的局部变量
        print(f'函数内部num:{num}')
    
        global m
        m = 200  # 要函数中修改一个全局变量的值,需要先用global进行说明
        print(f'函数内部m:{m}')
    
        global n
        n = 'abc'
    
    func3()
    print(f'函数外部num:{num}')  # 30
    print(f'函数外部m:{m}')  # 200
    print(f'函数外部n:{n}')  # abc
    

作业

  1. 编写一个函数,计算一个整数的各位数的平方和

例如: sum1(12) -> 5(1的平方加上2的平方) sum1(123) -> 14

def sum1(*nums):
    sum2 = 0
    for x in nums:
        sum2 += x**2
    return sum2
  1. 写一个函数,求一个数字列表中绝对值最大的元素

例如:nums = [-23, 100, 89, -56, -234, 123], 最大值是:-234

def max_absolute_value(list1):
    max1 = list1[0]
    for x in list1:
        if x**2 > (max1)**2:
            max1 = x
    return max1
  1. 编写函数实现字符串join方法的功能,将指定序列中的元素通过指定字符串合并成一个新的字符串

  2. 写一个函数实现列表extend的功能,将指定序列中的元素全部添加到指定列表中

    def extend(seq, list1):
        for x in seq:
            list1.append(x)
        return list1
    
  3. 写一个函数实现简易计算器的功能:输入第一个数字,输入运算符,输入第二个数字,计算结果。

    def operation(operator: str, *nums):
        if not nums or operator not in ('+', '-', '*', '/'):
            return None
    
        if operator == '+':
            sum1 = 0
            for x in nums:
                sum1 += x
            return sum1
    
        if operator == '*':
            sum1 = 1
            for x in nums:
                sum1 *= x
            return sum1
    
        if operator == '-':
            sum1 = nums[0]
            for x in nums[1:]:
                sum1 -= x
            return sum1
    
        if operator == '/':
            sum1 = nums[0]
            for x in nums[1:]:
                sum1 /= x
            return sum1
    
  4. 已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标)

    points = [ (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)]

    # 1)获取列表中y坐标最大的点
    def y_max_point(points):
        new_points = [abs(x[-1]) for x in points]
        return max(new_points)
    # 2)获取列表中x坐标最小的点
    def x_min_point(points):
        new_points = [abs(x[0]) for x in points]
        return min(new_points)
    # 3)获取列表中距离原点最远的点
    # 4)将点按照点到x轴的距离大小从大到小排序
    def sort(points):
        new_points = [abs(x[-1]) for x in points]
        new_points.sort(reverse=True)
        return new_points
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值