1、PythonPython语言程序设计语言程序设计第第8 8章章 函数与模块函数与模块2 第第8 8章章 函数与模块函数与模块 程序结构清晰,可读性好。减少重复编码的工作量。可多人共同编制一个大程序,缩短程序设计周期,提高程序设计和调试的效率。使用使用函数函数的的好处好处 函数是一组实现某一特定功能的语句集合,是函数是一组实现某一特定功能的语句集合,是可以重复调用、功能相对独立完整的程序段可以重复调用、功能相对独立完整的程序段。3 第第8 8章章 函数与模块函数与模块使用使用库函数库函数应注意:应注意:1、函数功能、函数功能2、函数参数的数目和顺序,及各参数意义和类型、函数参数的数目和顺序,及各
2、参数意义和类型3、函数返回值意义和类型、函数返回值意义和类型v用户自定义函数1.从用户的使用角度v库函数(标准函数):由系统提供 在程序前导入该函数原型所在的模块4 第第8 8章章 函数与模块函数与模块2.从参数传递的角度def average(x,y,z):aver=(x+y+z)/3;return(aver)a,b,c=eval(input(please input a、b、c:)ave=average(a,b,c)print(average=%f%ave)def printstar():print(*)def print_message():print(How are you!)def
3、main():printstar()print_message()printstar()main()有参函数有参函数无参函数无参函数5 第第8 8章章 函数与模块函数与模块8.2 函数的定义与调用函数的定义与调用定义一般形式:def 函数名(形式参数表):函数体 return 表达式l 采用采用def 关键字定义函数,不需要指定返回值的类型;关键字定义函数,不需要指定返回值的类型;l 函数的参数不限,不需要指定参数类型;函数的参数不限,不需要指定参数类型;l 参数括号后面的冒号参数括号后面的冒号“:”必不可少;必不可少;l 函数体相对于函数体相对于def关键字必须保持一定的空格缩进;关键字必须
4、保持一定的空格缩进;l return语句是可选的;语句是可选的;l 允许允许定义函数体为空的函数定义函数体为空的函数。函数函数定义定义时要时要注意注意6 第第8 8章章 函数与模块函数与模块一般形式:函数名(函数名(实际参数表实际参数表)说明v实参可以是常量、变量、表达式、函数等,但在 进行函数调用时必须有确定的值。v函数的实参和形参应在个数、类型和顺序上 一 一对应。v对于无参函数,调用时实参表列为空,但()不能省。7 第第8 8章章 函数与模块函数与模块例:编写函数,求例:编写函数,求3个数中的最大值。个数中的最大值。def getMax(a,b,c):if ab:max=a else:m
5、ax=b if(cm):max=c return maxa,b,c=eval(input(input a,b,c:)n=getMax(a,b,c)print(max=,n)在在Python中不中不允许前向引用,允许前向引用,即在函数定义即在函数定义之前,不允许之前,不允许调用该函数。调用该函数。8 第第8 8章章 函数与模块函数与模块8.3 函数的参数和函数的返回值函数的参数和函数的返回值形式参数:定义函数时函数名后面括号中的变量名实际参数:调用函数时函数名后面括号中对应的参数说明实参可以是常量、变量和表达式,但必须在函数 调用之间有确定的值。形参与实参个数相同形参定义时编译系统并不为其分配存
6、储空间,也无初值;只有在函数调用时,临时分配存储空间,接受来自实参的值;函数调用结束,内存空间释放。def average(x,y,z):aver=(x+y+z)/3;return(aver)a,b,c=eval(input(please input a、b、c:)ave=average(a,b,c)print(average=%f%ave)9 第第8 8章章 函数与模块函数与模块参数传递方式参数传递方式n单向的值传递单向的值传递 实参和形参之间是实参和形参之间是单向的值传递。单向的值传递。在函数调用时,在函数调用时,将各实参表达式的值计算出来,赋给形参变量。因此,将各实参表达式的值计算出来,
7、赋给形参变量。因此,实参与形参必须类型相同或赋值兼容,个数相等,一实参与形参必须类型相同或赋值兼容,个数相等,一一对应一对应。在函数调用中,即使实参为变量,形参值的。在函数调用中,即使实参为变量,形参值的改变也不会改变实参变量的值。改变也不会改变实参变量的值。实参和形参占用不同的内存单元实参和形参占用不同的内存单元n传地址方式传地址方式 函数调用时,将实参数据的存储地址作为参数传递函数调用时,将实参数据的存储地址作为参数传递给形参给形参10 第第8 8章章 函数与模块函数与模块def swap(a,b):a,b=b,a print(a=,a,b=,b)x,y=eval(input(input
8、x,y:)swap(x,y)print(x=,x,y=,y)运行结果:运行结果:input x,y:3,5a=5 b=3x=3 y=5形式参数(形参)形式参数(形参)实际参数(实参)实际参数(实参)例如:例如:编一程序,将主函数中的两个变量的值传递编一程序,将主函数中的两个变量的值传递给给swap函数中的两个形参,交换两个形参的值。函数中的两个形参,交换两个形参的值。单向值传递单向值传递11 第第8 8章章 函数与模块函数与模块def swap(a_list):a_list0,a_list1=a_list1,a_list0 print(a_list0=,a_list0,a_list1=,a_l
9、ist1)x_list=3,5swap(x_list)print(x_list0=,x_list0,x_list1=,x_list1)运行结果:运行结果:a_list0=5 a_list1=3x_list0=5 x_list1=3例:例:传地址方式。传地址方式。12 第第8 8章章 函数与模块函数与模块函数的返回值函数的返回值 指函数被调用、执行完后,返回给主调函数的值。指函数被调用、执行完后,返回给主调函数的值。函数的返回语句函数的返回语句一般形式一般形式 return 表达式表达式功能:功能:使程序控制从被调用函数返回到调用函数中,使程序控制从被调用函数返回到调用函数中,同时把返回值带给调
10、用函数同时把返回值带给调用函数def add(a,b):c=a+b x=add(3,20)print(x)说明v 函数内可有多条返回语句。v如果没有return语句,会自动返回NONE;如果有return语句,但是return后面没有表达式也返回NONE。13 第第8 8章章 函数与模块函数与模块例:编写函数,判断一个数是否是素数。例:编写函数,判断一个数是否是素数。def isprime(n):for i in range(2,n):if(n%i=0):return 0 return 1m=int(input(请输入一个整数请输入一个整数:)flag=isprime(m)if(flag=1)
11、:print(%d是素数是素数%m)else:print(%d不是素数不是素数%m)14 第第8 8章章 函数与模块函数与模块例:例:求一个数列中的最大值和最小值。求一个数列中的最大值和最小值。def getMaxMin(x):max=x0 min=x0 for i in range(0,len(x):if maxxi:min=xi return(max,min)a_list=-1,28,-15,5,10#测试数据为列表类型测试数据为列表类型x,y=getMaxMin(a_list)print(a_list=,a_list)print(最大元素最大元素=,x,最小元素最小元素=,y)strin
12、g=Hello x,y=getMaxMin(string)print(string=,string)print(最大元素最大元素=,x,最小元素最小元素=,y)15 第第8 8章章 函数与模块函数与模块8.4 函数的递归调用 在函数的执行过程中又直接或间接调用该函数本身 直接递归调用 在函数中直接调用函数本身间接递归调用 在函数中调用其它函数,其它函数又调用原函数f()调调f调调f2调调f1f1()f2()def a(x):z=b(y).return(2*z)def b(t):m=a(x).return(3+c)def f(x):z=f(y).return(2*z)16 第第8 8章章 函数与
13、模块函数与模块递归算法的两个基本特征递归算法的两个基本特征递推归纳递推归纳将问题转化为比原问题小的同类规模,归纳出一般递推将问题转化为比原问题小的同类规模,归纳出一般递推公式公式.故所处理的故所处理的对象要有规律地递增或递减对象要有规律地递增或递减递归终止递归终止当规模小到一定的程度应该结束递归调用,逐层返回当规模小到一定的程度应该结束递归调用,逐层返回常用条件语句来控制何时结束递归常用条件语句来控制何时结束递归 17 第第8 8章章 函数与模块函数与模块!1!2.)!2n()!1n(!n1 0 0n!时,例例 求递归方法求求递归方法求n的阶乘的阶乘)1()!1()1,0(1!nnnnn递推归
14、纳:递推归纳:递归终止:递归终止:def fac(n):if n=0:f=1 else:f=fac(n-1)*n;return fn=int(input(please input n:)f=fac(n)print(%d!=%d%(n,f)18 第第8 8章章 函数与模块函数与模块总结总结n执行过程(两个阶段)执行过程(两个阶段)第一阶段:逐层调用,调用函数自身第一阶段:逐层调用,调用函数自身 第二阶段:逐层返回,返回到调用该层的位第二阶段:逐层返回,返回到调用该层的位置置n递归调用是多重嵌套调用的一种特殊情况递归调用是多重嵌套调用的一种特殊情况n调用的深度:调用的深度:调用的层数调用的层数19
15、 第第8 8章章 函数与模块函数与模块n例:有例:有5个人,第个人,第5个人说他的年龄比第第个人说他的年龄比第第4个人大个人大2岁,岁,第第4个人说他的年龄比第个人说他的年龄比第3个人大个人大2岁,第岁,第3个人说他的个人说他的年龄比第年龄比第2个人大个人大2岁,第岁,第2个人说他的年龄比第个人说他的年龄比第1个人个人大大2岁;第一个人说他是岁;第一个人说他是10岁。请问第岁。请问第5个人多大?个人多大?2022年11月14日星期一思路:建立函数求个人的年龄,以每人的序号为参数,根据题意可知:age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age
16、(2)=age(1)+2 age(1)=10;即 age(n)=10 (n=1)age(n-1)+2 (n1)20 第第8 8章章 函数与模块函数与模块def age(int n):if n=1:c=10 else:c=age(n-1)+2 return cn=int(input(“input n:”)print(“%d”%age(n)age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10age(5)=18age(4)=16age(3)=14age(2)=12递归结递归结束条件束条件21 第第8 8章章 函数与
17、模块函数与模块前提:前提:1.原问题可以层层分解为类似的子问题,且子问题原问题可以层层分解为类似的子问题,且子问题比原问题规模更小比原问题规模更小2.规模最小的问题具有直接解规模最小的问题具有直接解方法:方法:1.寻找分解方法:将原问题转化为子问题求解,例:寻找分解方法:将原问题转化为子问题求解,例:n!=n*(n-1)!2.设计递归出口:根据规模最小的子问题确定递归设计递归出口:根据规模最小的子问题确定递归终止条件,例:求解终止条件,例:求解n!,当,当n0时,时,n!1;22 第第8 8章章 函数与模块函数与模块前提:前提:1.原问题可以层层分解为类似的子问题,且子问题原问题可以层层分解为
18、类似的子问题,且子问题比原问题规模更小比原问题规模更小2.规模最小的问题具有直接解规模最小的问题具有直接解方法:方法:1.寻找分解方法:将原问题转化为子问题求解,例:寻找分解方法:将原问题转化为子问题求解,例:n!=n*(n-1)!2.设计递归出口:根据规模最小的子问题确定递归设计递归出口:根据规模最小的子问题确定递归终止条件,例:求解终止条件,例:求解n!,当,当n0时,时,n!1;23 第第8 8章章 函数与模块函数与模块2022年11月14日星期一例:例:汉诺塔问题汉诺塔问题。设有三座塔座(。设有三座塔座(A、B、C),在一),在一个塔座(设为个塔座(设为A)上有)上有64个盘片,盘片不
19、等,按大盘个盘片,盘片不等,按大盘在下,小盘在上的顺序依次叠放。现要将在下,小盘在上的顺序依次叠放。现要将A塔上的盘塔上的盘片借助于片借助于B塔,移到塔,移到C塔上并保持同样顺序叠排,移塔上并保持同样顺序叠排,移动盘片时必须遵守以下规则:动盘片时必须遵守以下规则:(1)每次只能移动一个圆盘;(2)圆盘可以插在A、B、C任意一个塔座上;(3)任何时候都不能将一个较大的圆盘放到 较小的圆盘之上。24 第第8 8章章 函数与模块函数与模块2022年11月14日星期一 将将A塔上的红、黄两盘移动到塔上的红、黄两盘移动到B上上 蓝盘放到蓝盘放到C上上 将红、黄两盘从将红、黄两盘从B移动到移动到C盘上。(
20、完成)盘上。(完成)ABC问题分析:问题分析:(1)n=1时,直接将其从时,直接将其从AC;(2)n1时,只要先将前时,只要先将前n-1个借助个借助C从从AB,那么可以那么可以 把第把第n个直接从个直接从AC;(3)如何将剩下的)如何将剩下的n-1个圆盘遵守规则借助个圆盘遵守规则借助A从从BC,问题性质同(问题性质同(2);问题性质相同,因此适合问题性质相同,因此适合采用递归过程采用递归过程!25 第第8 8章章 函数与模块函数与模块n若将若将n个盘片按规定从个盘片按规定从A塔移至塔移至C塔,移动步骤可分为三步:塔,移动步骤可分为三步:把把A塔上的塔上的n-1个盘片借助个盘片借助C移动到移动到
21、B塔塔把第把第n个盘片从个盘片从A塔移至塔移至C塔塔把把B塔上的塔上的n-1个盘片借助个盘片借助A塔移至塔移至C塔塔算法用函数算法用函数hanoi(n,x,y,z)以递归算法实现以递归算法实现2022年11月14日星期一盘片数源塔借用塔目标塔 递归终止:当递归调用到盘片数为1时算法描述:算法描述:1)递归调用递归调用hanoi(n-1,a,c,b)2)将将n号盘片从号盘片从a塔移动到塔移动到c塔塔3)递归调用递归调用hanoi(n-1,b,a,c)26 第第8 8章章 函数与模块函数与模块count=0def hanoi(n,x,y,z):global count if n=1:count+=
22、1 move(count,x,z)else:hanoi(n-1,x,z,y);count+=1 move(count,x,z)hanoi(n-1,y,x,z);def move(n,x,y):print(step%d:Move disk form%c to%c%(count,x,y)m=int(input(Input the number of disks:)print(The steps to moving%d disks:%m)hanoi(m,A,B,C)27 第第8 8章章 函数与模块函数与模块8.5 变量的作用域变量的作用域 当程序中有多个函数时,定义的每个变量只能在一当程序中有多个函
23、数时,定义的每个变量只能在一定的范围内访问,称之为变量的作用域。定的范围内访问,称之为变量的作用域。按作用域划分,将变量分为按作用域划分,将变量分为局部变量和全局变量局部变量和全局变量。1.局部变量局部变量 在一个函数内或者语句块内定义的变量称为局部变在一个函数内或者语句块内定义的变量称为局部变量。局部变量的作用域仅限于定义它的函数体或语句块量。局部变量的作用域仅限于定义它的函数体或语句块中中。def fun1(a):x=a+10 def fun2(a,b):x,y=a,b 28 第第8 8章章 函数与模块函数与模块2.全局变量全局变量 在所有函数之外定义的变量称为全局变量,它可以在所有函数之
24、外定义的变量称为全局变量,它可以在多个函数中被引用在多个函数中被引用。x=30def func():global x print(x的值是的值是,x)x=20 print(全局变量全局变量x改为改为,x)func()print(x的值是的值是,x)29 第第8 8章章 函数与模块函数与模块8.6 模块模块 将一些常用的功能单独放置到一个文件中,方便其他将一些常用的功能单独放置到一个文件中,方便其他文件来调用文件来调用,这些文件即为模块。,这些文件即为模块。标准库模块标准库模块标准库模块是标准库模块是Python自带的函数模块自带的函数模块。文本处理文本处理 文件处理文件处理 操作系统功能操作系
25、统功能 网络通信网络通信 网络协议网络协议 从用户的角度看,模块也分为从用户的角度看,模块也分为标准库模块标准库模块和和用户自用户自定义模块定义模块。30 第第8 8章章 函数与模块函数与模块用户自定义模块用户自定义模块 用户建立一个模块就是建立扩展名为用户建立一个模块就是建立扩展名为.py的的Python程序程序。def printer(x):print(x)将以上程序代码保存成.py程序,例如module.py31 第第8 8章章 函数与模块函数与模块导入模块导入模块 导入模块就是给出一个访问模块提供的函数、对象导入模块就是给出一个访问模块提供的函数、对象和类的方法。和类的方法。(1)引入
26、模块)引入模块 import 模块模块(2)引入模块中的函数引入模块中的函数 from 模块名模块名 import 函数名函数名(3)引入模块中的所有函数引入模块中的所有函数 from 模块名模块名 import*32 第第8 8章章 函数与模块函数与模块例:采取插入排序法将例:采取插入排序法将10个数据从小到大进行排序。个数据从小到大进行排序。def insert_sort(array):for i in range(1,len(array):if arrayi-1 arrayi:temp=arrayi index=i while index 0 and arrayindex-1 temp:
27、arrayindex=arrayindex-1 index-=1 arrayindex=temp33 第第8 8章章 函数与模块函数与模块b=input(请输入一组数据:请输入一组数据:)array=for i in b.split(,):array.append(int(i)print(排序前的数据:排序前的数据:)print(array)insert_sort(array)print(排序后的数据:排序后的数据:)print(array)34 第第8 8章章 函数与模块函数与模块例:例:用递归的方法求用递归的方法求xn。递推归纳:递推归纳:递归终止:递归终止:def xn(x,n):if n=0:f=1 else:f=x*xn(x,n-1)return fx,n=eval(input(please input x and n)if n0:n=-n y=xn(x,n)y=1/yelse:y=xn(x,n)print(y)时当时当0n xx0n 1x1nnxnxn-1 xn-2 x2 x1当n=0时,x0=1