5.1 什么是函数?为什么要用函数?
什么是函数?
函数是专门定义的一个程序块,可以被其他程序块重复使用。这个描述有点抽象,可以举个例子,比如计算两个数的平均数,按照一般逻辑是要这样写:
1 | a = 10 |
后面的三行是平均数计算程序,先把两个变量加起来,然后除以2。这里就可以把这部分定义成一个函数,类似这样:
1 | def average_two_numbers(a, b): |
使用函数是这样:
1 | a = 10 |
这个 average_two_numbers 函数是定义了一个程序块,能接收2个参数 a 和 b,然后会计算两个数字的平均数并打印出来,这个函数可以被重复使用的,你可以传入任何2个数字都可以计算出平均数。
为什么要用函数?
函数可以把重复使用的程序块抽取出来,放到统一一个地方,然后在其他用到的地方重复调用。举个例子看一下,假设我们写个程序,要计算3次平均数,每次都是不同的两个数,如果不使用函数是类似这样代码:
1 | a = 10 |
有没有看到计算平均数的代码在重复?
现在看一下改成函数的代码:
1 | def average_two_numbers(a, b): |
现在有没有感觉代码清爽很多?可能还不够明显,如果计算平均数的代码有更多行,例如50行,感觉就会非常明显了,我们会把这50行都写在一个函数里,然后在使用时只需要一行代码调用这个函数就可以了,所以一个复杂的程序有了函数之后主程序也就是几段代码而已。
这样代码会清晰易懂,而且更重要的是更容易维护,如果我们想改动计算平均数的方法,只需要改动函数里面的代码就可以,调用函数的地方不需要改动。
举个现实中类似的例子,很多人都知道电脑上的 USB 接口,USB 接口其实就是定义了一个标准函数接口,规定了一些参数,只要符合 USB 接口的电子设备,比如鼠标、键盘等,可以插到 USB 接口使用,而这些电子设备本身可以多种多样,而且可以不断优化,只要按照 USB 接口的参数标准提供对外服务就可以。
Python 语言本身已经提供了很多内嵌函数,我们可以直接拿来用,像在我们示例代码里经常用的 print 函数。
我们在对象那一章节讲到的方法,其实也属于函数,只是方法一般是指一个对象本身的函数,也就是对象提供的可用函数,也一样可以有参数,有返回值。
函数这一章是比较抽象困难的部分,但也是必须要理解学会的部分。如果读完了之后没有理解,可以多实践操作和上网查资料。可以参考一下之前对 print 函数的介绍,更加直观,方便理解。
5.2 函数定义和使用方法
最简单的函数定义是这样写:
1 | def empty_func(): |
上面这个函数实际上没有发挥作用,是个空函数,里面的 pass 指令是跳过的意思,什么也不做。
我们看一下第一行 def empty_func(): 中的 def 是 Python 指令,后面的 empty_func 是我们给函数起的名字,后面的括号是指这个函数需要的参数,在这个例子里没有任何参数,所以括号里是空的,然后后面的冒号 : 跟以前的 if、for、while 等指令类似,是定义所属的程序块。
看一下上一节中那个有意义点的函数:
1 | def average_two_numbers(a, b): |
这个是定义一个名字叫 average_two_numbers 的函数,需要2个参数 a 和 b,里面的程序块是计算了 a 和 b 的平均数,并打印出来。
函数还有一个重要的概念是返回值,我们上面的例子是在函数里直接打印出了平均数计算结果,还有一种更常用的方式是把计算结果返回,由调用该函数的程序来考虑怎样展示出来,而不是每次都是在函数里打印出来,这个打印函数是在命令行里输出的,而实际场景可能是在一个网页里显示,或者在一个手机APP界面里显示。
我们看一下在函数里怎么用返回值:
1 | def average_two_numbers(a, b): |
从代码里可以看到,在函数程序块的最后一行 return d 是表示把计算结果返回,我们是把函数调用结果直接赋值给一个变量 result,然后再用 print(result) 打印出函数调用结果。
5.3 实践练习时间
过去章节我们学习了函数的概念和使用方法,下面通过几个实践练习来加深理解。
练习1:
定义一个函数,名字是 sum_list,传一个数值列表参数 list1,函数计算列表里各数值的和,然后返回。在主程序里定义一个数值列表,包含 10、20、30 这几个数字,然后调用刚才定义的函数,用这个数值列表作为参数,用一个变量获取到函数返回结果,最后打印出来。
(提示:这里的主程序就是用 python 程序文件名.py 命令时运行的程序代码,函数是属于主程序的一部分,但函数自己不会执行,需要被主程序调用后才能执行)
练习2:
定义一个函数,名字是 send_email,参数是 email 邮件地址和 content 邮件内容,函数里不进行实际的邮件发送操作,只是用 print 函数打印信息的方式模拟发送过程,先打印 “Connect to the email server…”,再打印 “Sending the email…”,再打印 “Sent successfully”。在主程序里使用这个函数。