《Python语言程序设计》 课件 第7章 函数_第1页
《Python语言程序设计》 课件 第7章 函数_第2页
《Python语言程序设计》 课件 第7章 函数_第3页
《Python语言程序设计》 课件 第7章 函数_第4页
《Python语言程序设计》 课件 第7章 函数_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第7章函数第7章

函数何时需要使用函数?7.1函数的定义与调用7.2函数参数7.3

特殊函数7.4装饰器7.5变量的作用域7.6模块7.7函数应用举例(1)计算机程序去解决一个复杂问题的时候,为降低程序难度,把一个复杂程序分解成若干规模较小的任务,分别由函数完成,然后由主程序去调用这些函数来解决复杂问题。什么时候使用函数?(2)程序功能单一且能反复使用。例如pow()、sqrt()、log(x)、input()等函数使程序模块化、减少代码重复率、清晰便于阅读7.1函数的定义与调用7.1.1函数定义

一类是由Python系统提供的系统函数如input()、print(),pow()等,系统函数可以直接被用户调用。另一类是用户自定义函数,由用户编写供人调用。用户自定义的函数的一般形式如下:def函数名([形参说明表]):函数语句体return表达式关键字def与函数名间要空格,函数名后面是一对小圆括号(),最后以冒号结束,函数语句体要缩进。函数可分为两类:return语句可以省略,函数将返回None。Python还允许函数体为空的函数,其形式为:def函数名():pass例7-1-1定义一个求两个数和的函数defadd(a,b):c=a+b

returnc或写成defadd(a,b):returna+ba,b为形式参数例7-1-2定义一个求n阶乘的函数deffact(n):

s=1forkinrange(1,n+1):s=s*kreturns当空函数被调用时什么也不做,定义空函数的目的是为了表示该此需要定义一个函数。n为形式参数1、以下正确定义函数首部语句()

A.defsum(): B.Defsum()C.defsum() D.Defsum():7.1.2函数的调用有参函数调用一般形式为:函数名(实际参数表)无参数函数调用形式为:函数名(

)用户自定义函数是不能直接运行,必须通过调用运行才能完成其功能。例7.3调用add()函数,实现两个数相加,并输出两数的和。defadd(a,b): c=a+breturnc s1=add(3,4)

S2=add(9,0)

print("s1=%d,s2=%d"%(s1,s2))调用add函数,3,4为实参调用add函数,9,0为实参程序运行结果:s1=7,s2=9例7-1-3编写程序,调用fact()函数,求整数n的阶乘n!(1)源程序代码deffact(m):s=1forkinrange(1,m+1):s=s*kreturnss=fact(3)调用函数fact(),3为实参print("3!=%d",s)n=eval(input("输入整数n:"))print("n!=%d",fact(n))调用函数fact(),n为实参(2)程序运行结果3!=6输入整数n:5↙5!=120defmyf(x,y):returnx*x+y*ydefmain():a,b=eval(input())print(myf(a,b))main()注:可以定义一个主函数,用于完成程序总体调度功能。例7-1-2,程序文件py.py的内容如下:程序运行结果如下:3,4↙25例7-1-4求五边形面积,长度k1~k7从键盘输入。分析:求五边形的面积可以变成求三个三角形面积的和。由于要三次计算三角形的面积,为了程序简单起见,可将计算三角形面积定义成函数。然后在主函数中三次调用它,分别得到三个三角形的面积,然后相加得到五边形的面积。例8-1程序如下:frommathimport*defts(a,b,c):s=(a+b+c)/2s=sqrt(s*(s-a)*(s-b)*(s-c))returnsdefmain():k1,k2,k3,k4,k5,k6,k7=eval(input(‘输入7条边:’))s=ts(k1,k2,k6)+ts(k6,k3,k7)+ts(k7,k4,k5)print("area=",s)main()其中,p=(a+b+c)/2。三角形面积公式为:1,3,6,9,5,8,4复杂程序通常由一个主程序以及多个函数模块组成。下图中,a.py是主程序,b.py和c.py是函数模块。函数模块b.py和c.py一般不直接执行,只能从主程序a.py开始。

复杂程序调用关系defadd(a,b):a=a+1b=b+1c=a+breturncx=5;y=6s=add(x,y)print('x={},y={}'.format(x,y))print("s1={}".format(s))调用add函数,x,y为实参程序运行结果:1、当实际参数为不可变对象时,实参对形参传递是值传递且单向,实参值传给形参,形参值不能回传给实参x=5,y=6s=13a,b为形式参数7.2函数参数7.2.1参数传递实参向形参传送数据的方式是值传递实参x=5,y=6...130…101150x56yb...217…203220a566a7b形式参数a,b传递给a=a+1b=b+1形参a,b的值改变了,但是不能回传给实参x,y2、当实际参数为可变对象时,是将实参地址传给形参,若函数调用中形参值被修改,则实参值相应修改例7-2-1阅读程序,了解实际参数为可变对象参数传递情况defupdate(num):num[0]=3num[2]=7num[4]=9if__name__=="__main__":list=[0,1,2,3,4,5]print("函数调用前结果:",list)update(list) print("函数调用后结果:",list)程序运行结果函数调用前结果:[0,1,2,3,4,5]函数调用后结果:[3,1,7,3,9,5]实参为可变对象时,实参存储地址传递给形参。这时,实参和形参共享内存存储单元。7.2.2参数的类型1.必需参数必需参数也称位置参数,调用时须以正确的顺序传入函数,实参的个数必须与形参个数一致且一一对应。执行上面程序时错误提示为“TypeError:take()missing1requiredpositionalargument:'z'”即:少了一个必需的位置参数z,若调用函数改为take(3,5,4),则输出结果为60。deftake(x,y,z):h=x*y*zreturnhk=take(3,5)print("输出结果为:",k)调用下面take()函数必须传入3个参数,否则会出现错误:Python中调用函数时,可使用的参数类型主要有必需参数、关键字参数、默认值参数和不定长参数等四类。defmykey(x,y):print("x=",x,"y=",y)mykey(y=10,x=20)2.关键字参数关键字参数的形式为:形参名=实参值可使用关键字参数指定形参的名称传递其对应的值,这可以跳过某些参数的顺序,不需要一一对应。程序运行结果如下:x=20y=10注意:默认值参数必须出现在形参表的最右端。若第一个形参使用默认值参数后,其后所有形参也必须使用默认值参数,否则会出错。3.默认值参数默认值参数的形式为:形参名=默认值例如:defmydefa(x,y=200,z=100):print("x=",x,"y=",y,"z=",z)mydefa(50,100)程序输出结果如下:x=50y=100z=1008以下程序的运行结果是()。defJc(m,n,k):s=m*n+k*ncreturnsy=Jc(k=5,2,4)print("y的输出结果为:",y)A)28B)5C)20D)程序运行时出错D7以下程序的运行结果是()。deffact(m,n=5,k):s=m*n+k*nreturnsy=fact(2,4)print("y的输出结果为:",y)A)30B)28C)20D)程序运行时出错Dy=Jc(2,4,k=5)Jc(k=5,m=2,n=4)fact(m,k,n=5):例如:defmyvar1(*t):print(t)myvar1(1,2,3)myvar1(1,2,3,4,5)4.不定长参数(1)元组不定长参数元组不定长度参数在参数名前面加*,用来接受任意多个实参并将其放在一个元组中。程序输出结果如下:(1,2,3)(1,2,3,4,5)例如:defmyvar2(**t):print(t)myvar2(x=1,y=2,z=3)myvar2(name='bren',age=25)(2)字典不定长度参数其表示方式是在函数参数名前面加**,可以接受任意多个实参。实参的形式为:关键字=实参值程序输出结果如下:{'y':2,'x':1,'z':3}{'age':25,'name':'bren'}defmytotal(x,y=30,*z1,**z2):

t=x+yforiinrange(0,len(z1)):t+=z1[i]forkinz2.values():t+=kreturnts=mytotal(1,20,2,3,4,5,k1=100,k2=200)print(s)例7-2-2阅读下列程序,写出程序的执行结果。程序输出结果:335函数调用后,x=1,y=20,z1=(2,3,4,5),z={‘k’:100,’k2’:200}先执行t=x+y=21其次,累加z1的值后t=35最后,累加z2的值后t=3353.下列程序的运行结果是()。deff(x=2,y=0):returnx-yy=f(y=f(),x=5)print(y)A.-3B.3C.2D.5B1.以下关于函数调用说法错误的是()。A.函数调用函数的实际参数和形式参数不需要同名。B.函数形参不用指定参数类型,Python会自动根据实参的值来确定参数的类型。C.函数的实际参数可以是表达式或常量。D.对于关键字参数,实参的个数必须与形参个数一致且一一对应。DC2.以下程序的运行结果是()。defmy(a,b,c=8):

returna+b+cprint(my(6,7,15))A)21B)不确定值C)28D)参数传递出错例如:lambdax,y:x+y7.3两类特殊函数7.3.1匿名函数1.匿名函数的定义匿名函数也称lambda函数,不需要用def定义,函数体只一行代码即一个表达式。代码运行结果被作为函数的返回值自动返回,且只有一个返回值。定义格式:lambda[参数1[,参数2,……,参数n]]:表达式2.匿名函数的调用例如:>>>f=lambdax,y:x+y>>>f(5,10)15注:参数可以有一个或多个,也可以缺省。f=lambdaa,b=2,c=5:a*a-b*cprint("Valueoff:",f(10,15))print("Valueoff:",f(20,10,38))print("Valueoff:",f(c=20,a=10,b=38))例7-3-1阅读程序,写出调用lambda函数的结果?Valueoff:25程序输出结果如下:#用默认值参数#用关键字实参Valueoff:20Valueoff:-660a=10,b=15,c=5a=20,b=10,c=38a=10,b=38,c=20deff():returnlambdax,y:x*x+y*yfx=f()print(fx(3,4))3.把匿名函数作为函数的返回值也可以把匿名函数作为普通函数的返回值返回。程序输出结果为:25可以序列或字典元素引用作为函数名来调用匿名函数,一般格式为:4.把匿名函数作为序列或字典元素可以将匿名函数作为序列或字典元素,以列表为例,一般格式为:列表名=[匿名函数1,匿名函数2,…,匿名函数n]列表或字典元素引用(匿名函数实参)>>>f['b'](3,4)例如:>>>f=[lambdax,y:x+y,lambdax,y:x-y]>>>print(f[0](3,5),f[1](3,5))8-2>>>f={'a':lambdax,y:x+y,'b':lambdax,y:x-y}>>>f['a'](3,4)7-11.下列程序的运行结果是()。f=[lambdax=1:x*2,lambdax:x**2]print(f[1](f[0](3)))A.1B.6C.9D.36D2下列程序的运行结果是()。 add=lambdax,y:y%x+y//xprint(add(9,2))A.5.5B.8.5C.1D.2D递归函数是指一个函数的函数体中又直接或间接地调用该函数本身的函数。7.3.2递归函数1.递归的基本概念deff(n):

ifn==1:

return2

else:

returnf(n-1)+2deff1(n):

deff2(n):…

z=f2(y)

y=f1(y)

间接递归

直接递归递归调用调用次数应该是有限次,任何一个递归调用程序必须包括两部分:(2)递归调用的结束条件,称为递归的边界条件。(1)递归循环继续的过程即递归公式。例7-3-2编写程序,利用递归调用方式求n!。分析:由于n!=n×(n-1)×(n-2)×(n-3)×…×2×1!,可得n!的递归公式为n!=n×(n-1)!。1!=1,因此,n=1是递归的边界条件,其边界值为1。deffac(n):ifn<=1:return1else:returnn*fac(n-1)m=fac(3)print(m)程序运行结果为:6fac(3)的计算流程1以下程序的输出结果是(

)deffib(n):ifn>2:returnfib(n-1)+fib(n-2)else:return3j=fib(4)print(j)92.下列代码运行后的结果是()。defsub(n):ifn<=1:return1else:returnn-sub(n-1)s=sub(5)print("{}".format(s))A.0B.1C.2D.3D例7.3-3编写程序,利用递归调用方式计算两整数m、n的最大公约数(其中m>n,且n≠0)。分析:本例采用辗转相除法来计算两个数m,n的最大公约数。过程:m除以n,如余数r=0,则n就是最大公约数。如r≠0,则m←n,n←r,再重复上述过程,直到r=0为止,这时的n就是要求的最大公约数.

例:m=112,n=77

被除数除数商余数

112/7713577/352735/750本问题的特点是要多次处理同一个问题,只是处理所用数据不同,且后一次所用数据为前一次处理的结果,正好用递归。源程序代码deffact(m,n):ifn==0:returnmelse:returnfact(n,n%m)if__name__=="__main__":m,n=eval(input("请输入n,m的值:"))s=fact(m,n)print("最大公约数为",s)程序运行结果输入m,n112,77↙两个数的最大公约数为:7例7-3-4写出以下递归函数程序的结果?defp(x,n):ifn==1:returnxelse:returnx*(1-p(x,n-1))print(p(2,3))程序运行结果为:61、装饰器本质上是一个函数,是用来包装函数的函数,经常用于为已经存在的函数添加额外的功能。7.4装饰器(Decorator)7.4.1无参数装饰器2、可将不同函数重复代码提取出来,将其定义为装饰器,然后由这些函数调用装饰器,从而实现代码的可重用性。defsquare_sum(x,y):returnx**2+y**2defsquare_diff(x,y):returnx**2-y**2print(square_sum(10,20))print(square_diff(10,20))程序运行结果:500-300例:下面程序定义了求两个数平方和与平方差的函数。现在要在这两个函数中增加输出原始数据x,y功能。defsquare_sum(x,y):

print("原始数据:",x,y)

returnx**2+y**2defsquare_diff(x,y):

print("原始数据:",x,y)

returnx**2-y**2print(square_sum(10,20))print(square_diff(10,20))程序运行结果:原始数据:1020500原始数据:1020-300defdeco(func):defnew_func(x,y):

print("原始数据:",x,y)

returnfunc(x,y)returnnew_func@decodefsquare_sum(x,y):returnx**2+y**2@decodefsquare_diff(x,y):returnx**2-y**2print(square_sum(10,20))print(square_diff(10,20))采用改写函数方法采用装饰器方法#调用装饰器#调用装饰器defDECO(argv):#定义新的带参数的装饰器defdeco(func):#原来的deco装饰器defnew_func(x,y):print(argv+"原始数据:",x,y)#输出原始数据returnfunc(x,y)returnnew_funcreturndeco7.4.2有参数装饰器

@DECO('Sum')#调用带参数装饰器defsquare_sum(x,y):#计算两个数的平方和returnx**2+y**2@DECO('Diff')#调用带参数装饰器defsquare_diff(x,y):#计算两个数的平方差returnx**2-y**2print(square_sum(10,20))print(square_diff(10,20))程序运行结果如下:Sum原始数据:1020500Diff原始数据:1020-300defdeco1(func):

print("deco1")returnfuncdefdeco2(func):print("deco2")returnfunc@deco2@deco1deffoo():print("foo")foo()程序运行结果如下:deco1deco2foo7.4.3多重装饰器多重装饰器,即多个装饰器修饰同一个函数。在一个函数体内或语句块内定义的变量称为局部变量,局部变量只在定义它的函数体或语句块内有效,而在定义它的函数体或语句块之外不能使用它。7.5变量的作用域1、局部变量在函数定义之外定义的变量称为全局变量,它可以被多个函数引用。2、全局变量例

阅读下面程序,了解局部变量的作用域,观察变量x、k和n的值。deffun(n):y=3k=2print("y=%d,k=%d,n=%d"%(y,k,n))returny+k+nfun(5)defmain():y=5k=6if(y>0):n=2*yelse:n=2*kprint("y=%d,k=%d,n=%d"%(y,k,n))main()y,k,n为局部变量,在函数fun内部有效y,k,n为局部变量,在函数main内部有效程序运行结果y=3,k=2,n=5y=5,k=6,n=10s=1 deff1():print(s,k)k=10 deff2():print(s,k)f1()f2()例

阅读下面程序,全局变量的作用域。#在函数外面定义全局变量s#在函数外面定义全局变量k变量s与k都是全局变量,在函数f1()和f2()中可以直接引用全局变量s和k。程序输出结果为:1101101.以下程序代码运行后的结果正确的是()。deffun():a=3b=9fun()print(a+b)A.3B.12C.9D.运行时出错D2.以下程序代码的运行结果正确的是()。a=10b=6deffun():a=13b=10fun()print(a+b)A.16B.10C.13D.23Adefchange(number,string,lst):number=5string='GoodBye'lst=[4,5,6]print("Inside:",number,string,lst)num=10string='Hello'lst=[1,2,3]print('Before:',num,string,lst)change(num,string,lst)print('After:',num,string,lst)After:10Hello[1,2,3]程序运行结果:例7-5-1阅读如下程序,分析程序运行结果#在函数中修改局部对象不会改变原始的实参值。Before:10Hello[1,2,3]Inside:5GoodBye[4,5,6]defchange(lst,dict):lst[0]=10dict['a']=10print('Insidelst={},dict={}'.format(lst,dict))dict={'a':1,'b':2,'c':3}lst=[1,2,3,4,5]print('Beforelst={},dict={}'.format(lst,dict))change(lst,dict)print('Afterlst={},dict={}'.format(lst,dict))例7-5-2阅读如下程序,分析程序运行结果Afterlst=[10,2,3,4,5],dict={'c':3,'a':10,'b':2}程序运行结果如下:对于可变列表或字典类型,局部区域的值是可以改变。Beforelst=[1,2,3,4,5],dict={'c':3,'a':1,'b':2}Insidelst=[10,2,3,4,5],dict={'c':3,'a':10,'b':2}若想在函数内部使用局部变量对函数外的全局变量进行修改,可以函数内部将其声明其为global变量,声明为global变量后,则局部变量变为全局量,以改变其值。例7-5-3.以下程序代码的运行结果正确的是()。a=10b=5deffun(b):globalaa=20b=b+afun(6)print("{},{}".format(a,b))A)20,26B)20,5C)10,5D)10,25B3、关键字global声明变量deff():globalx

#说明x为全局变量x=30y=40

#定义局部变量yprint("No2:",x,y)x=10

#定义全局变量xy=20

#定义全局变量yprint("No1:",x,y)f()print("No3:",x,y)No3:3020例7-5-4

写出以下程序输出结果。程序输出结果如下:No1:1020No2:3040deff():globalxx='ABC'defg():globalxx+='abc'returnxreturng()print(f())例7-5-5

写出程序的输出结果。ABCabc程序输出结果如下:Python提供了大量标准库模块,包括包括random、math、time和datetime、Internet编程、图形绘制、图形用户界面创建库等,这些为应用程序开发提供了强大支持。7.6模块7.6.1模块的定义与使用1.标准库模块2.用户自定义模块除标准库模块外,用户也可以自定义一个模块。定义一个模块实质上是建立一个Python程序文件。defpows(n):y=10**nreturny下面是一个简单的模块,程序文件名为support.py。from模块名import项目名1[,项目名2[,……,项目名n]]Python的from语句可以从一个模块中导入特定项目。也可以通过”from模块名import*”语句导入模块的所有项目。可以通过执行import语句导入Python模块1000>>>importsupport>>>support.pows(3)>>>fromsupportimportpows>>>pows(2)100例7-6-1

创建一个fibo.py模块,其中包含两个求Fibonacci数列的函数,然后导入该模块并调用其中的函数。deffib1(n):a,b=0,1whileb<n:print(b,end='')a,b=b,a+bprint()deffib2(n):result=[]a,b=0,1whileb<n:result.append(b)a,b=b,a+breturnresult首先创建一个fibo.py模块。1123581321345589144233377610987导入这个模块:>>>importfibo这里并没有把直接定义在fibo模块中的函数名称写入到语句中,所以需要使用模块名来调用函数。也可以一次性把模块中的所有函数,直接调用函数。1123581321345589144233377>>>fibo.fib1(1000)>>>fromfiboimport*>>>fib1(500)>>>fibo.fib2(300)[1,1,2,3,5,8,13,21,34,55,89,144,233]7.6.3模块的有条件执行Python中,模块本身也是一个程序文件,而程序文件是可以直接执行的。那么,我们如何来区分模块是被调用还是直接运行呢?每个模块都有一个名称,Python中有一个特殊变量__name__,它是一个全局变量,其可以获取每个模块的名称。若模块是被其他模块导入,__name__取值是模块本身的名称若模块文件是被用户直接执行,则__name__的取值是字符串“__main__”因此,可以通过__name__变量,可将一个模块既当作普通模块库供其他模块调用,又可当作一个执行文件进行执行。用import导入m.py时,__name__变量的值是模块名m,则不执行test()函数调用。deftest():print(__name__

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论