2022年8月

初识函数

定义
函数是指封装了某一特定功能的代码块。

简单的讲,函数就是用来存储代码的“特殊变量”。

前面接触过的很多“功能”都是函数。

比如在屏幕上输出一些数据的print(),生成一个指定范围整数序列的range()等。

函数的功能是如何定义的呢?

定义函数

def sayWelcome():
    print("欢迎光临")
    print("商品一律九折")

代码的作用
这3行代码做的事情是定义了一个叫做“sayWelcome”的函数。

这个函数的功能是输出欢迎语内容。

def
一个关键字,def函数定义的关键字,是define的缩写。

sayWelcome
一个名称,函数名。
这里的名称其实就是变量名,只不过需要存储的不再是数据,而是代码,我们称为函数名。

括号
一对括号,是函数定义的标准格式。

冒号
一个冒号,表明接下来缩进的代码是属于这个函数的。

缩进
四个空格。

和判断、循环一样,函数内部的代码也需要缩进相应的空格。

函数体
几行代码组成的代码块。

实现该函数功能的代码块,称为函数体。

代码小结
当我们要定义函数时就需要这几个部分。

现在我们已经将输出欢迎语的代码打包,并为它贴上了sayWelcome的标签。当我们需要展示欢迎语时,只需要“打电话”(call)给电脑,让它在此处执行sayWelcome的代码。

在代码中使用我们已经定义好的函数,这个过程称为调用函数(Call Function)。

调用函数

def sayWelcome():
    print("欢迎光临")
    print("商品一律九折")

sayWelcome()
sayWelcome()

代码的作用
定义一个sayWelcome函数,实现输出欢迎语的功能。

第5、6行代码,调用了sayWelcome函数。

sayWelcome
一个名称,被调用的函数名。

程序通过函数名来定位函数体中的代码。

括号
一对括号,调用符号。

表示在此处执行该函数中的代码,是调用函数的标准格式。

代码小结
当我们要调用函数时就需要这几个部分。

代码执行顺序
函数体中的代码不是立刻执行的,而是等到该函数被调用时才执行。

我们可以理解为:函数的调用是一个迂回的路径。

当程序执行到第七行代码时,开始调用setWatermark函数时,并不会继续执行第八行代码,而是跳转到定义函数setWatermark()的内部

从第二行开始执行

直到第2,3,4行代码结束

再跳回到第7行代码,从而继续执行第8行代码

现在我们可以把需要重复使用的代码定义为一个函数,就像刚才的sayWelcome函数。

若我们希望修改函数中的内容怎么办呢?

若定义函数时预留一个位置接收数据。根据不同的情况传递不同的数据,就能更加灵活的解决刚才的问题。

这时候我们需要为函数“挖空”,并在调用函数时“填空”,即设置参数。

我们把提前挖好的“空”称为形参,把用来填空的数据称为实参。

形参与实参

定义
形参是形式参数的简称,指定义函数时设置的参数名称。

实参是实际参数的简称,指调用函数时实际传递的数据。

为函数设置参数

def sayWelcome(discount):
    print("欢迎光临")
    print(f"商品一律{discount}")

sayWelcome("九折")
sayWelcome("五折")

代码的作用
定义sayWelcome函数,并为它们设置一个参数discount。

第1行,定义sayWelcome函数并在括号中设置形参名称discount。

第3行,将discount形参放到函数体中使用,使discount中的数据按照指定的格式输出。

第5~6行,多次调用sayWelcome函数,并分别为discount形参传递实参数据“九折”、“五折”。

形参
定义一个形参,用来接收数据的参数名称。

形参
在代码中使用形参,接收到的数据会被传递到此处使用。

实参
实参,调用函数时传递给形参discount的数据。

代码小结
我们通过下面的代码为函数设置参数。

形参
形参是定义函数时设置的参数名称。

相当于我们定义了一个变量,但不需要给该变量赋值。

实参
实参是调用函数时传递给形参的数据。

相当于为形参变量赋值的数据。

参数可以定义多个,也可以不定义。

如果参数不止一个,多个参数之间可以用英文逗号“,”隔开。

根据函数的功能不同,我们可以传递不同类型的实参数据。

比如,我们可以把店铺名称与产品折扣都设置为参数。

小练习

计算BMI指数
请定义一个叫做“getBMI()”的函数,该函数包括2个参数height, weight,分别代表身高和体重。

这个函数的功能是通过一个人的身高和体重计算BMI指数,并用print输出结果。

BMI指数的计算公式为:BMI = 体重 /(身高X身高)

然后分两次调用这个函数:

第一次传入参数(1.83, 60)。

第二次传入参数(1.60, 50)。

def getBMI(height, weight):
    BMI = weight / (height * height)
    print(BMI)

getBMI(1.83, 60)
getBMI(1.60, 50)

请定义一个叫做“isOdd”的函数,该函数包括1个参数number,代表一个整数。

这个函数的功能是通过if语句判断number中的数字是否为奇数,并用print输出结果。

若此数为奇数,输出“奇数”,否则输出“偶数”。 然后分两次调用这个函数:

第一次传入参数25。

第二次传入参数10。

# 定义isOdd函数
def isOdd(number):
    # 判断number是否为奇数
    if number % 2 == 1 :
        print("奇数")
    else :
        print("偶数")

# 调用isOdd函数
isOdd(25)
isOdd(10)

函数结构

假设,一位农场主想要统计自己的圈地面积有多少,面对大大小小的多个圈地,用代码该如何实现呢?

可以设定⼀个计算⾯积的函数,多次调⽤。

农场主的圈地均为正方形,测量面积的函数编写好后,如代码所示。

第 1 到第 3 行代码,定义了一个名为 getArea 的函数,用于计算正方形面积并输出。
第 5 和第 6 行代码,调用这个函数,传入参数,就可以获得不同边长的正方形面积大小。

def getArea(length):
    area = length*length
    print(area)

getArea(13)
getArea(7)

计算好了圈地的⾯积,想要计算边长为 13 的圈地⾯积是不是大于 160,如果大于 160 就用来种⻄⽠。

如本例所示,程序虽然输出了⾯积大小,但是不能在函数外比较数据的大小。
这是因为函数内输出的数据,没有传递到函数外。这时候,我们就需要设置函数返回值。

函数返回值

def getArea(length):
    area = length*length
    return area

result = getArea(13)
print(result)

代码的作用:
在本例中,第 1 到第 3 行代码定义了一个名为 getArea 的函数,其功能为计算正方形面积,并将结果返回。

第 5 行调用函数 getArea() 传入参数,将返回值赋值给变量 result

第 6 行代码,输出变量 result

return
在函数中,使⽤关键字 return 设置要返回的数据。
return 位置一般都是在函数的末尾,这样才能停止函数内的代码运行并将 return 后的值返回。

返回值
return 后面是指定的返回值,返回值会返回到调用的地方。

变量
调用函数 getArea(),传入参数 13,函数将运算结果 169 返回,并赋值给变量 result

代码小结
要定义函数和调用函数就需要这几个部分

在函数中使用关键字 return 时,要注意它的位置。
函数内部程序按照从上到下的顺序执行,如本例所示,函数内部有 for 循环,程序会等 for 循环执行完毕后,再执行 return 语句。
这样就可以得到传入列表中全部元素的累加值。

如果 return 的位置在函数的循环内部,函数内的循环只会执行一次。
因为执行到 return 语句,函数就返回当时的值,并且停止此次调用。

函数经过内部代码的执⾏会产⽣⼀个结果,这个结果可以是⼀个具体的值也可以是多个值。
在本例中,函数计算出正⽅形的周长和面积,函数返回了两个值。
当函数同时返回多个值时,以逗号 "," 隔开,并且返回值以元组的格式返回。

再来看这个案例。如图所示,左边的函数计算出正方形的面积,但是函数中没有 return 语句
此时,函数运行结束会返回一个空值(也就是None),作为返回值。

小练习

定义了一个叫做 "getSize" 的函数,该函数包含 1 个参数 length。

这个函数的功能是计算正方形周长和面积,并将两个结果作为函数的返回值返回。

现在分两次调用这个函数:
第一次传入参数 6 并输出结果。
第二次传入参数 8 并输出结果。

正方形周长 = 4 边长 正方形面积 = 边长 边长

def getSize(length):
    perimeter = 4*length
    area = length*length
    return perimeter,area

result = getSize(6)
print(result)
result = getSize(8)
print(result)

刚才农场主在函数中使用了 print(),程序输出了圈地面积,但是不能在函数外比较数据的大小。
在函数内使用 print() 可以得到数据,但是这个数据不能在函数外使用。
在函数内使用 return 可以将数据传递到函数外。

学完了函数结构中的每个部分,总结⼀下函数的结构。

函数名
为函数取名是为了方便我们重复使用。在 Python 中,函数的命名规则和变量类似。

参数
参数可以理解为函数的输入。
形参指定义函数时设置的参数名称,实参指调用函数时实际传递的数据。在本例中,num 为形参,8 为实参。
参数可以定义多个,也可以不定义。如果参数不止一个,多个参数之间用英文逗号 “,” 隔开。

函数体
函数体是函数内部实现特定功能的代码。就像做菜之前需要先想好具体的烹饪方式,等到做菜的时候再使用一样。
在本例中,函数体是为了计算一个数的二次幂(平方)和三次幂(立方)。

返回值
返回值可以理解为函数的输出。
就像对做菜的原材料进行烹饪加工,最后会得到我们想要的菜品一样,函数经过内部代码的执行也会产生一个结果。
这个结果可以是具体的值,也可以是一项具体的操作。

调用函数
在代码中使用我们已经定义好的函数,这个过程称为调用函数。
调用函数获得的返回值,可以用一个变量存储下来,就可以在函数外使用这个数据了。

代码小结
函数的结构

学习了函数结构后,还有一类函数就不得不提。
既然函数的使用顺序是先定义后调用,之前使用的很多函数, 比如 print()range()append() 等等,它们没有被我们定义,为什么还能直接被使用呢?
是因为,在 Python 中还有一类函数叫内置函数。

内置函数

和其他编程语言一样,Python也会将一些经常使用的函数预先写好,内置在编程环境中,提供许多常用的基本功能。
这些函数不需要我们去定义,可以直接使用,也被称为内置函数。

程序中使用内置函数也就是在调用函数。
例如,调用 len() 函数,它可以返回字符、列表、元组等长度或元素个数。

如图所示:
len 为函数名;
() 为调用符号,在此处执行该函数中的代码;
列表 ["a","b","c","d"] 为实参。

程序将 len(["a","b","c","d"]) 的返回值 4 ,赋值给变量data;接着,输出变量data。