函数是什么?

本节Python培训教程是要大家认识一个"老朋友"——函数。

与数学中的函数不同,在Python中,函数不是看上去冰冷无聊的规则和公式,而是实打实的、有自己作用的代码。

之所以说函数是我们的老朋友,是因为我们已经接触过一些Python自带(学名叫"内置")的函数了。

比如我们要"打印",就会用到 print ;我们要"获取数据长度",就会用到 len 。这些都是设定好的,可以直接拿来用的功能。

函数(Function)能实现的功能各式各样,但本质想通:"喂"给函数一些数据,它能内部消化,"吐"给你想要的东西。

就像自动贩卖机,喂点钱,吐出来一些吃喝用的东西;Python函数喂各种各样的数据,吐出来各种各样的功能。

python中函数定义的规则 python函数的定义_Python

眼尖的你会发现图片函数后面跟了个括号。而括号里面的就是我们需要输入的数据,它在函数中被称为【参数】。参数指向的是函数要接收、处理怎样的数据。

说了这么多函数的特征,现在我们一起看看函数的定义:

python中函数定义的规则 python函数的定义_Python_02

还是用贩卖机来打比方,贩卖机是设定好可以直接使用(组织好的),可以重复上架售卖不同物品(重复使用),功能是卖东西(单一功能)。

好,现在问题来了,就像贩卖机不总是有我们要的东西,除了Python自带的内置函数,我们能不能根据自己编写程序的需求,定义自己的函数呢?

答案是肯定的,下面我们就来DIY一个函数。

定义和调用函数

第一步,我们需要去定义一个函数,想象函数的名字、功能是什么。

定义函数

要定义函数,你要这样写:

python中函数定义的规则 python函数的定义_Python_03

照着这个语法,我们先来举个最简单的例子,定义一个打招呼的函数。

python中函数定义的规则 python函数的定义_python中函数的定义_04

来一起读代码。第一行:def的意思是定义(define),greet是【函数名】(自己取),再搭配一个括号和冒号,括号里面的name是参数(也自己取)。

第2行:def下一行开始缩进的代码是函数要实现的功能,也叫【函数体】。这里的函数体展现的功能就是:打印出"name+good morning"这句话。

第3行:一个简单的return。函数内部一旦遇到return,就会停止执行并返回结果,没有return语句的函数,Python也会在末尾隐形加上return None,即返回None值(return None可以简写为return)。所以你也会看到,我们接下来的很多例子是省略了return语句。

python中函数定义的规则 python函数的定义_局部变量_05

看到第3行注释,你会有些疑惑,怎么括号里可以有参数,也能没有参数?接下来我举个小例子,你可以对比一下。

python中函数定义的规则 python函数的定义_python中函数的定义_06

这几个函数都是打印出句式相同的话,区别在于第一个函数总是输出固定的一句话,所以不需要带参数。

而第二个函数需要参数name的参与,所以括号里面要带上name,第三个则需要两个参数来完成功能。所以说,参数的数量需要视函数想要什么功能来设置。

运行上面代码后我们发现,终端一片空白。这就对了。

截止目前,我们完成了【定义函数】。但定义函数只是将函数的内部功能封装起来(组织好)。

定义完函数的下一步就是调用函数,召唤神奇宝贝的时刻到了。

调用函数

怎么调用函数呢?很简单,喊出它的名字即可。在Python里,就是输入函数名和参数对应的值。就像这样:

python中函数定义的规则 python函数的定义_全局变量_07

通过这个例子,我们明白调用函数最关键的是:得弄清楚这个函数有多少参数,如何给参数赋值,这个过程在函数里叫做参数的传递。

那么,定义和调用函数的基本语法就讲的差不多了。为了让大家理解基本概念,目前举的例子都只是实现非常简单的功能。

例如,这个tree()函数能打印出一颗圣诞树,参数是圣诞树的层高。

python中函数定义的规则 python函数的定义_python中函数的定义_08

这样下次祝别人圣诞快乐的时候就可以把圣诞树送给TA啦!

函数重要概念

前面我们提到,设置与传递参数是函数的重点。而善解人意Python呢,支持非常灵活的参数形态。我们就先来了解一下这些参数类型。

主要的参数类型有:位置参数、默认参数、不定长参数。我会用一个案例将这些参数串起来。

假设你最近开了一家深夜食堂,顾客随意点菜,因为人手不足,所以只能为每个人提供一份开胃菜和一份主食。如果写成函数,这个函数就会有两个参数。

python中函数定义的规则 python函数的定义_全局变量_09

这里的'话梅花生'和'牛肉拉面'是对应参数appetizer和course的位置顺序传递的,所以被叫做【位置参数】,也是最常见的参数类型。

回到深夜食堂,经营一段时间后,为吸引更多客流,你决定给每个顾客送一份免费甜品绿豆沙,这时候你可以用到默认参数,注意:默认参数必须在位置参数后。

python中函数定义的规则 python函数的定义_Python_10

如果一个参数的值是相对固定的,那么设置默认参数就免去了每次都要传递的麻烦,但默认参数并不意味着不能改变。

了解完默认参数,我们接下来看。

后来,你觉得买烧烤是个好主意,但每个客人点的烤串数量不同,你也不能限定死数量,这时候【不定长参数】就能派上用场,即不确定传递参数的数量。

它的格式比较特殊,是一个*星号加上参数名,来看下面的例子。

python中函数定义的规则 python函数的定义_python中函数的定义_11

你会发现输出的是这样的结果:('烤鸡翅','烤茄子','烤玉米'),这类数据类型叫做元组(tuple)。

和列表一样,元组是可迭代对象,这意味着我们可用for循环来遍历它,这时候代码就成了:

python中函数定义的规则 python函数的定义_Python_12

需要注意的是,这时候默认参数也需要放在不定长参数的后面,即dessert = '绿豆沙' 要放在 *barbeque后面,否则传递的值会对不上。

现在,你明白参数不同形态,以后就可视实际情况的需要,灵活设置不同的参数类型啦。

接下来,我们着重讲下函数的第二个拓展概念:return语句。

return语句

前面我们提到,return是返回值,当你输入函数,函数会返回一个值给你。实际上每个函数都有返回值,像我们学过的len()函数。

在自定义函数的时候,我们可以用return语句规定该函数要返回什么值给我们。

在很多时候,当多个函数之间相互配合,我们并不需要第一时间就将结果打印出来,而是需要将某个返回值先放着,等到需要的时候再做进一步的处理。

python中函数定义的规则 python函数的定义_Python_13

下面来看个例子:

在关于爱情的天真幻想中,我希望我的梦中情人拥有xxx的脸蛋和xxx的身材。

现在需求如下:一、分别定义两个函数,参数为人名,能够返回字符串'XXX的脸蛋'和'XXX的身材';二、将上述两个函数的返回值拼接在一起后,再打印出来。

python中函数定义的规则 python函数的定义_python中函数定义的规则_14

这是一个非常简单的例子,在类似这种多个函数相互配合的代码中,我们就非常需要return语句,来帮我们保留其个函数的返回值,等到要用的时候再调出来。

但是这样的代码有个问题,当我想多次调用函数的时候,就需要先复制print那行代码,再分别修改两个函数里的参数。这样的操作不简洁和优雅。就像这样:

python中函数定义的规则 python函数的定义_Python_15

所以更常见的做法是:再定义一个主函数main(),参数调用前两个函数的返回值。

main()函数内部分别调用了face()和body()函数,参数dream_face和dream_body传递给了face()和body()函数的参数name,得到返回值,并打印。看起来有点绕,我们将函数运行的步骤分解,就一目了然。

python中函数定义的规则 python函数的定义_python中函数定义的规则_16

我们可以总结一下:

python中函数定义的规则 python函数的定义_局部变量_17

接下来我们要讲return一个特别的用法,我们看到前面所有的return语句,都是返回1个值,如果要返回多个值,我们该怎么办?

python中函数定义的规则 python函数的定义_python中函数的定义_18

事实上,Python语言中的函数返回值可以是多个,而其他语言都不行,这是Python相比其他语言的简便和灵活之处。一次接受多个返回值的数据类型就是元组。

而元组与列表其实都是数据的"序列",元组取某个位置的操作,与列表一模一样的,即tuple[]。因此,我们会这样去写代码。

现在你大概对return的作用有了更深的了解吧。我们继续总结:

python中函数定义的规则 python函数的定义_python中函数的定义_19

此外,return还有一个"副作用":一旦函数内部遇到return语句,就会停止执行并返回结果。

好啦,关于return的语句,我们知识讲解就到这里。

python中函数定义的规则 python函数的定义_Python_20

好,return讲完了,现在我们来看最后一个函数重要概念,变量作用域。

变量作用域

当我们定义一个函数的时候,很重要的事情就是理解函数中变量的作用域。下面请先认真看下面两行字:

1.在一个函数内定义的变量仅能在函数内部使用(局部作用域),它们被称作【局部变量】。

2.在所有函数之外赋值的变量,可以在程序的任何位置使用(全局作用域),它们叫【全局变量】。

认真看完了吗?我们来看一个例子。

python中函数定义的规则 python函数的定义_Python_21

你可以看到,两个变量都叫x,一个在函数外部,一个在函数内部。

因为x = 99 是在函数外赋值的,所以第一个变量x是全局变量;x = 88 是在函数内部赋值的,所以第二个变量x是局部变量。

python中函数定义的规则 python函数的定义_局部变量_22

虽然变量的名字相同(都是x),但是因为全局变量和局部变量处在不同的"作用域"中,所以它们彼此进水不犯河水,都能打印出相应的结果。

但为了让程序更易读以及避免可能出现的麻烦,建议局部变量和全局变量【不要】取相同的名字,以免混淆。

你可以将定义的函数想象成一个私人房间,所以里面存数据的容器(变量)是私有的,只能在个人的房间里使用;而在函数外存的变量是公用的,没有使用限制。

python中函数定义的规则 python函数的定义_Python_23

有几点需要注意!就像你不希望合租的人随意使用你私人房间里的物品,全局作用域中的代码也不能使用任何局部变量,来看看一个新手容易踩的坑:

这段代码运行后发现,第4行代码问题:NameError:name 'quantity' is not defined(变量quantity没有被定义)。

其实,我们是定义了,只不过在函数egg()内定义的,所以这个是局部变量。但问题我们不能在定义的函数egg()外面,也就是不能再全局作用域中使用这个局部变量。

python中函数定义的规则 python函数的定义_全局变量_24

那怎么办?其实也很简单,就像私人房间里的人可以自由使用公共区域的物品,在函数内部的局部作用域,是可以访问全局变量的。

python中函数定义的规则 python函数的定义_python中函数的定义_25

虽然计算机成功把变量quantity打印出来,这是因为全局变量在哪里都可以被使用。

总之,当变量处于被定义的函数内时,就是局部变量,只有函数内被访问;当变量处于被定义函数外时,就是全局变量,可以在程序中任何位置被访问。

如果你非要将局部变量变成全局变量,就像把私人房间内的东西挪到公共区域,可不可以呢?Python也能满足你,只不过用到新的语句 global 语句,就像这样:

python中函数定义的规则 python函数的定义_Python_26

呼,今天的课到这里就结束了~知识点看起来很多,是因为函数是Python里非常重要的工具!只有掌握了这些基础,我们才能敲出炫酷的代码。