• Python函数和代码复用


    在这里插入图片描述

    🤵‍♂️ 个人主页: @Flyme awei 个主页
    👨‍💻 作者简介:Python领域新星创作者。
    🐋 希望大家多多支持😘一起进步呀!
    📝 如果文章对你有帮助的话,欢迎评论💬点赞👍收藏📂加关注

    前言

      今天是《CSDN21天学习挑战赛》的第14天
      昨天学习了Python基本数据类型——字符串
      今天将学习Python的函数和代码复用

    活动地址:CSDN21天学习挑战赛

      python的学习还是得基础知识+自己动手同步进行。如果是python新手,需要找一个可以在线练习得网站,我建议你去牛客网多练习。
    在这里插入图片描述

    Python函数和代码复用

    什么是函数:

      函数是一段具有特定功能的,可重用的语句组,通过函数名来表示和调用。经过定义,一组语句等于一个函数,在需要使用这组语句的地方,直接调用函数名称即可。因此,函数包括两部分:函数的定义函数的调用

    为什么要使用函数:

    • 代码复用
    • 影藏实现细节
    • 提高可维护性
    • 提高可读性便于调试
    • 降低编程难度

    一、函数的定义

    语法格式:

    def  函数名 ([参数列表]):
        函数体
        return 返回值列表 
    
    • 1
    • 2
    • 3

    例:

    # -*- coding: utf-8 -*-
    # @File  : demo.py
    # @author: Flyme awei 
    # @email : Flymeawei@163.com
    # @Time  : 2022/8/14 17:02
    
    def calc(a, b):  # 函数定义
        c = a + b
        return c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    二、函数的调用

    函数的定义也叫函数“声明”,定义后的函数不能直接运行,需要经过“调用”才能得到运行。

    语法格式:

    函数名(实际赋值参数列表)
    
    • 1
    # 函数创建
    def calc(a, b):  # 函数定义
        c = a + b
        return c
    
    '''
    函数调用:
    函数名(实际参数列表)'''
    d = calc(10, 20)  # 函数调用
    print(d)  # 30
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    三、函数的参数传递

    函数的参数在定义时可以指定默认值,当函数被调用时,如果没人传入对应的参数时,则使用函数定义时的默认值替代。

    语法格式

    def  函数名(非可选参数列表,可选参数列表=默认值):
        函数体
        return 返回值列表 
    
    • 1
    • 2
    • 3

    1.形式参数与实际参数

    • 函数定义处的参数称为形式参数
    • 函数调用处的参数称为实际参数

    2.位置传参与关键字传参

    # -*- coding: utf-8 -*-
    # @File  : demo.py
    # @author: Flyme awei 
    # @email : Flymeawei@163.com
    # @Time  : 2022/8/14 17:02
    
    # 函数的参数传递
    '''
    1.位置传参 根据形参对应的位置进行参数传递
    2.关键字实参 根据形参名称进行参数传递
    '''
    
    def calc(a, b):  # a b 为函数定义当处的形式参数
        c = a + b
        return c
    
    
    calc(10, 20)  # 10 20 为函数调用处的实际参数
    
    # 位置实参
    print(calc(10, 20))  
    
    # =左侧的变量的名称称为关键字参数
    print(calc(b=10, a=20))  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    3.可变对象与不可变对象的参数传递

    在函数调用过程中,进行参的传递:

    • 如果是不可变对象,函数体的修改不会影响实参的值
    • 若果是可变对象,函数体的改变会影响到实参的值
    # -*- coding: utf-8 -*-
    # @File  : demo.py
    # @author: Flyme awei 
    # @email : Flymeawei@163.com
    # @Time  : 2022/8/14 17:02
    
    '''
    在函数调用过程中,进行参的传递:
    如果是不可变对象,函数体的修改不会影响实参的值
    若果是可变对象,函数体的改变会影响到实参的值
    '''
    
    
    def fun(arg1, arg2):
        print('arg1=', arg1)
        print('arg2=', arg2)
        arg1 = 100  # arg1 的修改为100不会影响n1的值
        arg2.append(200)  # are2 的修改会影响到n2的值
        print('arg1=', arg1)  # 100
        print('arg2=', arg2)  # [10, 20, 200]
        return arg1, arg2
    
    
    a = 10
    b = [10, 20]
    print('a', a)  # 10
    print('b', b)  # [10, 20]
    x = fun(a, b)  # 位置传参 arg1,arg2时是函数定义处的形参,n1,n2是函数调用处的实参, 实参和形参的名称可以不一致
    print(a)  # 10
    print(b)  # [10, 20, 200]
    print(x)  # (100, [10, 20, 200])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    在这里插入图片描述

    4.个数可变的位置、关键字参数

    • 个数可变的位置参数: *arges

    参数定义时,可能无法事先确定传递的位置实参的个数,使用可变的位置参数

    • 个数可变的关键字形参:**kwargs

    参数定义时,可能无法事先确定传递的位置实参的个数,使用可变的位置参数

    在一个函数的定义过程中,既有个数可变的 *arges位置形参,又有个数可变的**kwargs关键字形参,要求把位置形参放在前面

    # -*- coding: utf-8 -*-
    # @File  : demo.py
    # @author: Flyme awei 
    # @email : Flymeawei@163.com
    # @Time  : 2022/8/14 17:02
    
    
    # 个数可变的位置参数 *arges
    # 参数定义时,可能无法事先确定传递的位置时参的个数,使用可变的位置参数
    
    def fun(*args):  # 函数定义时,可变的位置参数
        print(args)  # 返回值为元组
        # print(args[0])  返回元组的第1个对象
    
    
    fun(10)  # (10, )
    fun(10, 20)  # (10, 20)
    fun(11, 22, 33)  # (11, 22, 33)
    
    
    # 个数可变的关键字形参
    # 参数定义时,可能无法事先确定传递的位置是参的个数,使用可变的位置参数
    def fun(**kwargs):
        print(kwargs)  # 返回值是 字典
    
    
    fun(a=10)  # {'a': 10}
    fun(a=10, b=20, c=30)  # {'a': 10, 'b': 20, 'c': 30}
    
    '''
    def fun2(*args,*a)
        pass
    以上程序报错,个数可变的的位置参数值能有一个
    def fun2(**kwargs)
        pass
    个数可变的关键字参数也只能有一个
    '''
    
    # 在一个函数的定义过程中,既有个数可变的位置形参,又有个数可变的关键字形参,要求把位置形参放在前面
    def fun(*args, **kwargs):
        pass
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    在这里插入图片描述

    5.函数参数总结(一)

    # -*- coding: utf-8 -*-
    # @File  : demo.py
    # @author: Flyme awei 
    # @email : Flymeawei@163.com
    # @Time  : 2022/8/14 17:02
    
    
    def fun(a, b, c):  # a,b,c在函数定义处,所以是形式参数
        print('a=', a)
        print('b=', b)
        print('c=', c)
    
    
    # 函数调用
    fun(10, 20, 30)  # 函数调用时的参数传递,称为位置传参
    lst = [11, 22, 33]
    fun(*lst)  # 函数调用,将列表中的每个元素都转换为位置实参传递
    
    fun(a=100, b=200, c=300)  # 函数调用,所以是关键字实参
    dic = {'a': 111, 'b': 222, 'c': 333}
    print(fun(**dic))  # 函数调用时,将字典中的键值对都转换为关键字实参传递
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    6.函数参数总结(二)

    def fun(a, b=10):  # a是形式参数
    
        print('b=', b)
    
    
    def fun2(*args):  # 个数可变的位置形参
        print(args)
    
    
    def fun3(**kwargs):  # 个数可变的关键字形参
        print(kwargs)
    
    
    # 函数调用
    fun(10)
    fun(10, 20)
    fun2(10, 20, 30)
    fun3(a=10, b=20)
    print('--------------------------')
    
    
    def fun4(a, b, *, c, d):  # 需求 c,d 只能采用关键字实参传递
        print('a=', a)
        print('b=', b)
        print('c=', c)
        print('d=', d)
    
    
    # fun4(10, 20, 30, 40)   # 位置实参传递
    fun4(a=10, b=20, c=30, d=40)  # 关键字实参传递
    print('--------------------------')
    fun4(10, 20, c=30, d=40)  # 前面两个进行位置实参传递,后面两个采用关键字实参传递
    
    ''' 函数定义时的形参顺序问题'''
    
    
    def fun5(a, b, *, c, d, **kwargs):
        pass
    
    
    def fun6(*args, **kwargs):
        pass
    
    
    def fun7(a, b=10, *args, **kwargs):
        pass
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    在这里插入图片描述

    四、函数的返回值

      return语句用来结束函数并将程序返回到函数调用的位置继续执行。return语句可以出现在函数中的任何部分,同时可以将0个、1个或多个函数运算的结果返回给函数被调用处的变量。

    函数的返回值

    1. 如果没有返回值(函数执行完毕后,不需要给调用处提供数据),return可以省略不写
    2. 若果返回值为1个,直接返回类型原类型
    3. 如果返回值为个,返回结果为元组
    # -*- coding: utf-8 -*-
    # @File  : demo.py
    # @author: Flyme awei 
    # @email : Flymeawei@163.com
    # @Time  : 2022/8/14 17:02
    
    '''
    函数的返回值:
    (1)如果没有返回值(函数执行完毕后,不需要给调用处提供数据),return可以省略不写
    (2)若果返回值为1个,直接返回类型原类型
    (2)如果返回值为多个,返回结果为元组
    '''
    
    
    def fun(lst):
        odd = []
        even = []
        for i in lst:
            if i % 2:
                odd.append(i)
            else:
                even.append(i)
        print(odd, even)
        return odd, even  # 没有返回值,可以省略  如果返回值为多个,返回结果为元组
    
    
    lst1 = [12, 34, 45, 57, 67, 78, 89]
    print(lst1)
    
    # 函数调用
    print(type(fun(lst1)))
    '''函数定义时,是否需要返回值,视情况而定'''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    五、变量的作用域

    变量的作用域:程序代码能访问该变量的区域

    1. 局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会变成全局变量

    2. 全局变量:函数体外定义的变量,可作用于函数内外

    # -*- coding: utf-8 -*-
    # @File  : demo.py
    # @author: Flyme awei 
    # @email : Flymeawei@163.com
    # @Time  : 2022/8/14 17:02
    
    # 变量的作用域:程序代码能访问该变量的区域
    '''
    1.局部变量 在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会变成全局变量
    2.全局变量 函数体外定义的变量,可作用于函数内外
    '''
    
    
    def fun(a, b):
        c = a+b  # c,在函数内定义的变称为局部变量  a,b为函数的形参,作用范围也在在函数内部,相当于局部变量
        print(c)
    
    
    name = '阿伟'  # 函数外部定义的变量,全局变量,函数体内外都可以使用
    print(name)  # 阿伟
    
    
    def fun2(self):
        print(name)
    # 函数调用
    
    
    fun2(name)  # 阿伟
    
    
    def fun3():  # 函数定义
        global age  # 函数内部定义的变量,局部变量  使用global声明,变量就变为全局变量
        print(age)  # 20
    
    
    age = 20
    fun3()  # 函数调用
    print(age)  # 20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    在这里插入图片描述

    六、代码复用

      函数是程序的一种基本抽象方式,它将一系列代码组织起来通过命名供其他程序使用。函数封装的直接好处是代码复用,任何其他代码只要输入参数即可调用函数,从而避免相同功能的代码在被调用处重复编写。代码复用有另一个好处,当更新函数功能时,所有被调用处的功能都被更新。

      程序由一系列代码组成,如果代码是顺序但无组织的,不仅不利于阅读和理解,也很难进行升级和维护。当程序长度在百行以上,如果不划分模块,程序的可读性就已经很糟糕了。解决这一问题最好的方法是将一个程序分割成短小的程序段,每一段程序完成一个小的功能。使用函数对合理划分为功能模块,并基于模块设计程序是一种常用方法,被称为“模块化设计”。

      模块化设计是指函数的封装功能将程序划分成主程序、子程序和子程序间关系的表达。模块化设计是使用函数设计的思考方法, 以功能块为基本单位,一般有两个基本要求:

    • 紧耦合:尽可能合理划分功能块,功能块内部耦合紧密;
    • 松耦合:模块间关系尽可能简单,功能块之间耦合度低。

       使用函数只是模块化设计的必要非充分条件,根据计算需求合理划分函数十分重要。一般来说,完成特定功能或被经常复用的一组语句应该采用函数来封装,并尽可能减少函数间参数和返回值的数量。

    七、递归函数

    1.什么是递归函数

    如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数。

    2.递归的组成部分

    递归调用递归终止条件

    3.递归的调用过程

    每递归调用一次函数,都会在栈内存分配一个栈帧,每执行完一次函数,都会释放相应的空间。

    4.递归的优缺点

    缺点:占用内存多,效率低下
    优点:思路和代码简单

    • 使用递归函数计算阶乘
    # 1.使用递归函数计算阶乘
    def fun(n):  # 阶乘函数
        if n == 1:
            return 1
        elif n == 2:
            return 2
        else:
            return n * fun(n-1)
    
    
    print(fun(6))  # 720
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 斐波那契数列
    # 2.斐波那契数列 1 1 2 3 5 8 13 ...
    def fib(n):  # 斐波那契函数
        if n == 1:
            return 1
        elif n == 2:
            return 1
        else:
            return fib(n - 1) + fib(n - 2)  # 求斐波那契数列的第 n 项
    
    
    print(fib(6), end=' ')  # 8
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    八、总结

    • 函数使用def定义
    • *args定义个数可变的位置形参
    • **kwargs定义个数可变的关键字形参
    • 变量=值定义默认值形参
    • 函数调用的实参:位置实参关键字实参
    • 变量的作用域:局部变量全局变量

    推 荐:牛客题霸-经典高频面试题库

    🌐 找工作神器-|笔试题库|面试经验|大厂面试题 👉 点击链接进行注册学习
    在这里插入图片描述

  • 相关阅读:
    Java IO 中的 FileInputStream 和 FileOutputStream
    Linux-3-进程创建与进程状态
    如何合并多个PDF文件?这几个小妙招快来码住吧
    php数据表操作
    webpack自定义loader解析指定后缀名文件
    Ubuntu安装Redis
    MySQL 数据库查询缓存
    港口数字化发展不是噱头,是现状也是趋势
    数据分析----numpy快速入门
    Android 12.0 framework关于systemUI定制之导航栏透明背景的功能实现
  • 原文地址:https://blog.csdn.net/m0_68744965/article/details/126336332