Python复习小记 第七章 函数(上)

7.1 函数的概念

函数可以理解为实现某种功能的代码块,这样当程序中需要这个功能时就可以直接调用,而不必每次都编写一次。这就好比生活中使用计算器来计算,当需要计算时,直接使用计算器输入要计算的数,计算完成后显示计算结果,而不必每次计算都通过手写演算出结果。
在程序中,如果需要多次输出“拼搏到无能为力,坚持到感动自己!”,则可以将这个功能写成函数,具体示例如下:
在这里插入图片描述当需要使用该函数时,则可以使用以下语句:
在这里插入图片描述

该条语句可以多次使用。函数使减少代码冗余成为现实,并为代码维护节省了不少力气。
Python中的函数分为内建函数和自定义函数。内建函数是Python自带的,即可以直接使用,如print()函数、input()函数等。常见的内建函数如表所示,本章主要介绍自定义函数。
在这里插入图片描述

7.2 函数的定义

内建函数的数量是有限的,如果大家想自己设计符合使用需求的函数,则可以定义一个函数,其语法格式如下:

在这里插入图片描述
在上述语法格式中,需注意以下几点:
def(即define,定义)为关键字,表示定义一个函数。
函数名是一个标识符,注意不能与关键字重名。
小括号之间可以用于定义参数,参数是可选的,但小括号不可少。
函数体以冒号起始,并且缩进。
函数体的第一行语句可以选择性地使用文档字符串用来存放函数说明。
return [表达式]结束函数,将表达式的值返回给调用者,也可以省略。
接下来演示一个简单的自定义函数,如例所示。
在这里插入图片描述
在例中,第2~7行为文档字符串,初学者在初学阶段只需了解即可。若想查看一个函数的文档字符串,则可以通过__doc__属性,如第11行所示。关于自定义函数sum2num()的解释,如图所示。
在这里插入图片描述

定义函数后,就相当于有了一个具有某些功能的代码。如果想让程序执行这些代码,则需要调用之前定义的函数,其语法格式如下:
在这里插入图片描述
在例中,求3与4的和时,则可以通过以下语句实现:
在这里插入图片描述

7.3 函数的参数

参数列表由一系列参数组成,并用逗号隔开。在调用函数时,如果需要向函数传递参数,则被传入的参数称为实参,而函数定义时的参数称为形参,实参与形参之间可以传递数据。

7.3.1 位置参数

位置参数是指函数调用时传递实参的顺序与定义函数的形参顺序一致,如例所示。
在这里插入图片描述

在例中,第1、2行定义printInfo()函数。第3行调用该函数,其数据传递如图所示。第4行将两个实参的位置调换,则发生错误。

在这里插入图片描述

在图中,当函数调用时,实参的传递顺序与定义函数形参的顺序需保持一致。由于实参的顺序与函数定义时形参的位置有关,因此称为位置参数。

7.3.2 关键参数

关键参数是指通过对形参赋值传递的参数。关键参数允许函数调用时传递实参的顺序与定义函数的形参顺序不一致,因为 Python解释器能够用形参名匹配实参值,使用户不必记住位置参数的顺序,如例所示。
在这里插入图片描述
运行结果如图所示。
在这里插入图片描述

在例中,第1~2行定义printInfo()函数。第4行调用函数,其参数是根据函数定义时形参的名称进行数据传递,因此称为关键参数。

7.3.3 默认参数

如果在函数定义时参数列表中的某个形参有值,就称这个参数为默认参数。注意默认参数必须放在非默认参数的右侧,否则函数将出错,如例所示。
在这里插入图片描述
运行结果如图所示。
在这里插入图片描述
在例中,第3行调用函数时,由于定义函数时形参school有默认值’千锋教育’,因此调用时可以省略不写该参数。如果想修改默认值,则在调用时传入该参数即可,如本例中的第4行。
默认参数可以让函数的调用更加简化,就如同安装PC端软件时,程序会提示用户默认安装路径,当然用户也可以自定义安装路径。
此外,如果将例题中的name与school调换位置,具体示例如下:
在这里插入图片描述
程序运行后,将会报错,如图所示。
在这里插入图片描述

7.3.4 不定长参数

在前面对函数的介绍中,一个形参只能接收一个实参。除此之外,函数形参可以接收不定个数的实参,即用户可以给函数提供可变长度的参数,这可以通过在形参前面使用来实现,如例所示。
在这里插入图片描述
此外,不定长参数还可以接受关键参数并将其存放到字典中,这时需要使用**来实现,如例所示。
在这里插入图片描述
此外,通过
还可以进行相反的操作,如例所示。
在这里插入图片描述

另外,通过**可以将字典转换为关键参数,如例所示。
在这里插入图片描述
此外,需注意上述两种方式的传递顺序,如例所示。
在这里插入图片描述

7.3.5 传递不可变与可变对象

在Python中,数字、字符串与元组是不可变类型,而列表、字典是可变类型,两者区别如下:
不可变类型——该类型的对象所代表的值不能被改变。当改变某个变量时,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。
可变类型——该类型的对象所代表的值可以被改变。变量改变后,实际上是其所指的值直接发生改变,并没有发生复制行为,也没有开辟出新的地址。
接下来演示调用函数时传递不可变与不可变对象,如例所示。
在这里插入图片描述
运行结果如图所示。

在这里插入图片描述

7.4 函数的返回值

函数调用时的参数传递实现了从函数外部向函数内部输入数据,而函数的return语句实现了从函数内部向函数外部输出数据。
此处需注意,如果函数定义时省略return语句或者只有return而没有返回值,则Python将认为该函数以“return None”结束,None代表没有值,如例所示。
在这里插入图片描述
return语句可以放置在函数中任何位置,当执行到第一个return语句时,程序返回到调用程序处接着执行,此时不会执行该函数中return语句后的代码,如例所示。
在这里插入图片描述
当函数具有多个返回值时,如果只用一个变量来接收返回值,函数返回的多个值实际上构成了一个元组,如例所示。

在这里插入图片描述
运行结果如图所示。
在这里插入图片描述

7.5 变量的作用域

变量起作用的代码范围称为变量的作用域,与变量定义的位置密切相关,按照作用域的不同,变量可分为局部变量和全局变量。

7.5.1 局部变量

在函数内部定义的普通变量只在函数内部起作用,称为局部变量。当函数执行结束后,局部变量自动删除,不可以再使用,如例所示。
在这里插入图片描述
运行结果如图所示。
在这里插入图片描述

7.5.2 全局变量

如果需要在函数内部给一个定义在函数外的变量赋值,那么这个变量的作用域不能是局部的,而应该是全局的。能够同时作用于函数内外的变量称为全局变量,它通过global关键字来声明,如例所示。
在这里插入图片描述
此处需注意,如果不使用global声明,则在函数中访问的是局部变量,如例所示。
在这里插入图片描述

此外,使用内置函数globals()与locals()可以查看局部变量与全局变量,如例所示。
在这里插入图片描述
在例中,函数globals()与locals()分别返回一个字典,通过打印字典中的元素,可以查看全局变量与局部变量。另外,在函数内部可以通过global关键字直接将一个变量声明为全局变量,即使在函数外没有定义,则该函数执行后,这个变量将成为全局变量,如本例中的变量z。

7.6 函数的嵌套调用

Python语言允许在函数定义中出现函数调用,从而形成函数的嵌套调用,如例所示。
在这里插入图片描述
在例中,第6行在fun2()函数中调用fun1()函数,程序执行时会跳转到fun1()函数处去执行,执行完fun1()后,接着执行fun2()函数中剩余的代码,如图所示。
在这里插入图片描述

7.7 函数的递归调用

在函数的嵌套调用中,一个函数除了可以调用其他函数外,还可以调用自身,这就是函数的递归调用。递归必须要有结束条件,否则会无限地递归(Python默认支持997次递归,多于这个次数将终止)。
接下来演示函数的递归调用,如例所示。
在这里插入图片描述
在例中,第10行到第12行定义f()函数用于计算阶乘。当n == 0时,程序立即返回结果,这种简单情况称为结束条件。如果没有结束条件,就会出现无限递归。当n > 0时,就将这个原始问题分解成计算n – 1阶乘的子问题,持续分解,直到问题达到结束条件为止,就将结果返回给调用者,然后调用者进行计算并将结果返回给它自己的调用者,该过程持续进行,直到结果返回原始调用者为止。原始问题就可以通过将f(n-1)的结果乘以n得到,这种调用过程就称为递归调用,如图所示。
在这里插入图片描述

7.8.1 案例一

编写两个函数,一个函数接收一个整数num为参数,生成杨辉三角形前num行数据,另一个函数接收生成的杨辉三角形并按以下形式输出,如图所示。
在这里插入图片描述
在图中,列出了杨辉三角形的前9行。每一层左右两端的数都是1并且左右对称,从第1层开始,每个不位于左右两端的数等于上一层左右两个数相加之和。
在图中,列出了杨辉三角形的前9行。每一层左右两端的数都是1并且左右对称,从第1层开始,每个不位于左右两端的数等于上一层左右两个数相加之和。
在这里插入图片描述

7.8.2 案例二

汉诺塔问题是源于印度一个古老传说,大梵天创造世界时,在世界中心贝拿勒斯的圣庙中做了3根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘(称为汉诺塔)。大梵天命令婆罗门把圆盘从一根柱子上按大小顺序重新摆放在另一根柱子上,并规定在三根柱子之间一次只能移动一个圆盘且小圆盘上不能放置大圆盘,如图所示。
在这里插入图片描述

假设使用1,2,3,…,n标记n个大小互不相同的圆盘,A、B、C标记3个柱子,初始状态时所有圆盘都放在A柱子上,最终状态时所有的圆盘都放在C柱子上,柱子B作为中间缓冲。
当n = 1时,即只有1个圆盘,此时可以直接把这个圆盘从柱子A移动到柱子C,这也是递归的终止条件。
当n > 1时,依次解决以下三个子问题:
借助柱子C将前n-1个盘子从柱子A移到柱子B
将圆盘n从柱子A移到柱子C
借助柱子A将前n-1个圆盘从柱子B移到柱子C
汉诺塔问题的具体实现如例所示。
在这里插入图片描述

总结

本章主要介绍了Python中函数的基本知识,包括函数的定义、函数的参数、函数的返回值、函数的嵌套调用与递归调用。通过本章的学习,应熟练掌握如何自定义函数、如何设置函数的参数。另外,在实际编写程序时,应尽量使用函数来简化一些代码,提高代码的可读性、可重用性及可维护性。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值