函数介绍
# 函数定义的语法格式
def 函数名(形式参数列表)
函数体
return 返回值
- 形式参数列表可以包含多个形式参数,使用逗号分隔开
- return 语句可以有也可以没有,不是必须的
- 函数必须先定义,再使用
代码的警告与错误
- 警告:代码可能存在问题,但是不影响编译运行
- 错误:代码存在不可忽视的问题
- 编程规范:PEP8是Python中很流行的一套编程规范(编程的“软性要求”);我们以后使用哪一种编程规范取决于公司的要求
函数的返回值
- 编程的通用原则:一个函数只做一件事情
- 下面展示的是两种编程方案,在实际开发过程中更推荐第二种
- 第一个版本既做了计算,又做了打印(和用户交互);而第二个版本只完成计算任务
- 逻辑处理与用户交互分离的好处是解耦合(交互带来耦合,而良好的编程设计应该让耦合降低)
Python中函数可以同时返回多个值(通过多元赋值和_接受返回值,如下所示)
作用域
- 函数和类的变量名的作用范围有限,只在作用域内生效
- if、elif、else、while、for这些结构没有作用域的范围,变量的生效范围没有被限制
- 局部变量和全局变量重名时,局部变量优先
- 当我们想要在函数的作用域中使用全局变量时,可以使用global关键字声明
函数的执行过程
- 可以使用Pycharm的调试器,观察函数的执行过程
- 断点的作用是让程序在此处停止,然后通过step into让程序单步运行
- 下面的第三张图则代表模块调用栈,描述了模块之间的调用关系
函数的链式调用和嵌套调用
链式调用:通过连续调用多个函数来达到简化代码的目的
嵌套调用:一个函数在其内部调用另一个函数
局部变量和函数栈帧
- 调试器的左下角可以观察到函数之间的“调用栈”
- 一个函数被调用时,会在内存中创建一个称为栈帧的数据结构,用于管理函数的执行上下文;函数的调用结束,则对应的栈帧消亡
- 主要作用:存储局部变量、保存函数参数、记录返回地址......
函数递归
- 递归代码写法简单,但是执行过程可能会非常复杂
- 递归代码的分析用脑子思考是很困难的,可以借助画图或者调试器
- 递归的两个要素:递归结束条件和递归的递推公式
- 缺点:执行过程复杂;容易发生栈溢出;递归一般都可以转换成循环
- 优点:方便处理一些用递归定义的问题,如数据结构的二叉树
函数形式参数的默认值
函数的关键字参数
- 函数传参的两种方式:位置传参、关键字传参(按照形式参数的名字传参)
def test(x,y) # 函数体 test(y = 10,x = 8)
- 位置参数和关键字参数可以混着用,但是位置参数需要放在前面,关键字参数需要放在后面
- 关键字参数其实默认就是搭配位置参数使用的
- 拥有很多形式参数的函数可以对函数内部功能不断调整,为了降低使用成本就会将大部分形式参数设定为默认值
- 函数使用者需要调整其中的一部分参数时,就可以使用关键字参数来进行操作(此处暂时做一个了解,后续设计文件的知识会进一步学习)