第七章 函数
一、函数的概念:
Python中的函数分为内建函数和自定义函数。内建函数是Python自带的,即可以直接使用,如print()函数、input()函数等。常见的内建函数如表所示,本章主要介绍自定义函数。
一、函数的定义:
1.内建函数的数量是有限的,如果大家想自己设计符合使用需求的函数,则可以定义一个函数,其语法格式如下:
2.注意:
(1)def(即define,定义)为关键字,表示定义一个函数。
(2)函数名是一个标识符,注意不能与关键字重名。
(3)小括号之间可以用于定义参数,参数是可选的,但小括号不可少。
(4)函数体以冒号起始,并且缩进。
(5)函数体的第一行语句可以选择性地使用文档字符串用来存放函数说明。
(6)return [表达式]结束函数,将表达式的值返回给调用者,也可以省略。
3.定义函数后,就相当于有了一个具有某些功能的代码。如果想让程序执行这些代码,则需要调用之前定义的函数,其语法格式如下:
三、函数的参数
1.参数列表由一系列参数组成,并用逗号隔开。在调用函数时,如果需要向函数传递参数,则被传入的参数称为实参,而函数定义时的参数称为形参,实参与形参之间可以传递数据。
(1)位置参数:位置参数是指函数调用时传递实参的顺序与定义函数的形参顺序一致。(2)关键参数:关键参数是指通过对形参赋值传递的参数。关键参数允许函数调用时传递实参的顺序与定义函数的形参顺序不一致,因为 Python解释器能够用形参名匹配实参值,使用户不必记住位置参数的顺序。
(3)默认参数:如果在函数定义时参数列表中的某个形参有值,就称这个参数为默认参数。注意默认参数必须放在非默认参数的右侧,否则函数将出错,默认参数可以让函数的调用更加简化,就如同安装PC端软件时,程序会提示用户默认安装路径,当然用户也可以自定义安装路径。
(4)不定长参数:在前面对函数的介绍中,一个形参只能接收一个实参。除此之外,函数形参可以接收不定个数的实参,即用户可以给函数提供可变长度的参数,这可以通过在形参前面使用来实现,通过还可以进行相反的操作,此外,不定长参数还可以接受关键参数并将其存放到字典中,这时需要使用来实现,通过可以将字典转换为关键参数
(5)传递不可变与可变对象:
在Python中,数字、字符串与元组是不可变类型,而列表、字典是可变类型,两者区别如下:
不可变类型——该类型的对象所代表的值不能被改变。当改变某个变量时,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。
可变类型——该类型的对象所代表的值可以被改变。变量改变后,实际上是其所指的值直接发生改变,并没有发生复制行为,也没有开辟出新的地址。
四、函数的返回值:
1.函数调用时的参数传递实现了从函数外部向函数内部输入数据,而函数的return语句实现了从函数内部向函数外部输出数据。
2.注意:如果函数定义时省略return语句或者只有return而没有返回值,则Python将认为该函数以“return None”结束,None代表没有值。
3.return语句可以放置在函数中任何位置,当执行到第一个return语句时,程序返回到调用程序处接着执行,此时不会执行该函数中return语句后的代码。
五、变量的作用域:
变量起作用的代码范围称为变量的作用域,与变量定义的位置密切相关,按照作用域的不同,变量可分为局部变量和全局变量。
1.局部变量:在函数内部定义的普通变量只在函数内部起作用,称为局部变量。当函数执行结束后,局部变量自动删除,不可以再使用。2.全局变量:如果需要在函数内部给一个定义在函数外的变量赋值,那么这个变量的作用域不能是局部的,而应该是全局的。能够同时作用于函数内外的变量称为全局变量,它通过global关键字来声明。
注意:如果不使用global声明,则在函数中访问的是局部变量。此外,使用内置函数globals()与locals()可以查看局部变量与全局变量。
六、函数的嵌套调用:
1.Python语言允许在函数定义中出现函数调用,从而形成函数的嵌套调用
2.在函数的嵌套调用中,一个函数除了可以调用其他函数外,还可以调用自身,这就是函数的递归调用。递归必须要有结束条件,否则会无限地递归(Python默认支持997次递归,多于这个次数将终止)。
七、lambda函数(重点):
1.Lambda函数是一个匿名函数,有时也被称为lambda表达式,比def格式的函数定义简单很多。
2.Lambda函数可以接受任意多个参数,只返回一个表达式的值。
3.Lambda中不能包含多个表达式。
4.其中的形式参数可以有多个,他们之间用逗号隔开。
5.表达式只有一个。
6.返回表达式的计算结果。
八、递归:
1.函数内部可以调用其他函数。
2.一个函数在内部直接或间接地调用自己本身,这是一种递归的方法。
3.递归调用是通过栈来实现的,分为递推过程和回归过程:
(1)递推过程:每调用一次自身,把当前参数压栈,直接达到递归终止条件。
(2)回归过程:从栈中弹出当前的参数,直到栈空。