《Python语言基础及应用》 课件 第5章 函数_第1页
《Python语言基础及应用》 课件 第5章 函数_第2页
《Python语言基础及应用》 课件 第5章 函数_第3页
《Python语言基础及应用》 课件 第5章 函数_第4页
《Python语言基础及应用》 课件 第5章 函数_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

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

文档简介

第5章函数函数的定义与调用Lambda模块实验:递归遍历文件实验:学员管理系统contents目录函数基本概念与定义调用函数参数类型与返回值处理函数嵌套调用与递归实现函数高级特性探索错误处理与调试技巧总结回顾与拓展延伸contents函数的定义与调用函数基本概念与定义调用01函数定义和调用标准的自我介绍尝试在交互式Python环境中展示该例子,可以选择使用四个print语句,或者利用换行符\n将四句话合成一个print语句输出。Hello, Mynameis<insert-name>,I’m<insert-age>yearsold.Nicetomeetyou!函数定义和调用下面的交互式会话创建了一个程序,进行自我介绍(Lily,25)#5-1print("Hello,")print("MynameisLily,")print("I’m25yearsold.")print("Nicetomeetyou!") 输出:Hello,MynameisLily,I’m25yearsold.Nicetomeetyou!

函数定义和调用自定义函数格式def函数名(参数表):

函数体根据该格式,通过引入一个函数并使用参数,可以将上述的自我介绍模板转换成一个名为introduction的通用函数。#5-2-1 defintroduction(name,age): ①

'''显示简单的自我介绍''' ②print("Hello,")print("Mynameis{},".format(name))print("I’m{}yearsold,".format(age))print("Nicetomeetyou!")函数定义和调用自定义函数格式def函数名(参数表):

函数体利用introduction函数为不同人打印自我介绍时,需要在调用函数时提供该人的姓名和年龄作为参数。#5-2-2 introduction("Fred",30)print()introduction("Elle",27)print()

输出:Hello,MynameisFred,I’m30yearsold,Nicetomeetyou!

Hello,MynameisElle,I’m27yearsold,Nicetomeetyou!

03函数定义后可以被多次调用,而不需要重复编写相同的代码。01函数是一种组织好的、可重复使用的、用来执行特定任务的代码块。02函数能提高应用程序的模块性和代码的重复利用率。函数定义和调用函数名应该能够反映函数的功能,最好使用动词或动名词组合。函数定义时,需要指定函数的参数类型和返回值类型(在静态类型语言中)。函数体内部应该包含实现函数功能的代码逻辑,并且要保证代码的可读性和可维护性。自定义函数格式规范函数参数类型与返回值处理02123按照函数定义中参数的顺序传入,一一对应。位置实参传入时指定参数名,无需考虑顺序。关键字实参位置实参适用于参数较少、顺序固定的函数;关键字实参适用于参数较多、顺序不固定或需要

强调参数意义的函数。应用场景位置实参和关键字实参区别及应用场景introduction(27,"Elle") 输出:Hello,Mynameis27,I’mElleyearsold,Nicetomeetyou!

introduction(age=27,name="Elle") 输出:Hello,MynameisElle,I’m27yearsold,Nicetomeetyou!

设置默认值在函数定义时,为参数指定默认值。注意事项默认值应为不可变类型,以避免潜在的问题调用方式调用函数时,如未传入该参数,则使用默认值;如传入该参数,则使用传入的值。默认值参数设置技巧defintroduction(name,age=18): print("Hello,")print("Mynameis{},".format(name))print("I’m{}yearsold,".format(age))print("Nicetomeetyou!")introduction("Elsa")print()introduction("Stella",33)输出:Hello,MynameisElsa,I’m18yearsold,Nicetomeetyou!

Hello,MynameisStella,I’m33yearsold,Nicetomeetyou!

调用方式的选择可混合使用位置实参、关键字实参和默认值。不匹配错误当实参和形参个数不匹配时,将出现实参不匹配错误注意>>>defintroduction(name,age=18): print("Hello,")

print("Mynameis{},".format(name))

print("I’m{}yearsold,".format(age))

print("Nicetomeetyou!")>>>introduction()TypeError:introduction()missing1requiredpositionalargument:'name'传递方式将列表作为参数传入函数。函数内部操作函数内部可以对列表进行修改,这些修改会影响到原始列表。传递引用列表在传递时实际上是传递引用,而非复制。列表作为参数传递方法#5-3defhello(names):fornameinnames:print('Hello!'+name)name_list=['Lily','Fred','Elle']hello(name_list)

输出:Hello!LilyHello!FredHello!Elle

传递方式将列表作为参数传入函数。函数内部操作函数内部可以对列表进行修改,这些修改会影响到原始列表。传递引用列表在传递时实际上是传递引用,而非复制。列表作为参数传递方法#5-4defwaiting(wait,finish):"""候补名单,排队等叫号录入信息,直到候补名单清零。完成录入的人将被移至finish列表"""wait_copy=wait[:]for_waitinwait_copy:

print('Next,'+_wait+'please!')

finish.append(_wait)

wait.remove(_wait)deffinished(finish):"""显示完成进度"""

for_finishinfinish:

print('TheInfoof{}hasbeensaved.'.format(_finish))waiting_list=['Lily','Fred','Elle']finished_list=[]waiting(waiting_list,finished_list)finished(finished_list)输出:Next,Lilyplease! Next,Fredplease!Next,Elleplease!TheInfoofLilyhasbeensaved.TheInfoofFredhasbeensaved.TheInfoofEllehasbeensaved.任意数量实参处理策略使用星号(*)在函数定义时使用一个带星号的参数可以接收任意数量的位置实参,并将其保存为一个元组。调用方式调用函数时,可以传入任意数量的位置实参,这些实参会被收集到元组中#5-5 defhello(*names):fornameinnames:print('Hello!'+name)

hello('Lily','Fred','Elle')print()hello('Elsa')

输出:Hello!LilyHello!FredHello!Elle

Hello!Elsa

任意数量实参处理策略使用星号(*)在函数定义时使用一个带星号的参数可以接收任意数量的位置实参,并将其保存为一个元组。调用方式调用函数时,可以传入任意数量的位置实参,这些实参会被收集到元组中#5-6 defhello(group,*names):"""向各组别的成员打招呼"""print('Hereisgroup{}:'.format(group))fornameinnames:print('Hello!'+name)

hello('4-1','Lily','Fred','Elle')print()hello('4-2','Elsa')

输出:Hereisgroup4-1:Hello!LilyHello!FredHello!Elle

Hereisgroup4-2:Hello!Elsa

在函数定义时使用一个带双星号的参数,可以接收任意数量的关键字实参,并将其保存为一个字典。调用函数时,可以传入任意数量的关键字实参,这些实参会被收集到字典中。任意数量关键字实参处理策略调用方式使用双星号(**)#5-7profile={}

defintroduction(name,**person):"""创建一个字典,其中包含知道的有关用户的一切"""person['name']=nameprofile[name]=person

introduction('Fred',age=30,career='Engineer')introduction('Elle',age=27)

print(profile)

输出:{'Fred':{'age':30,'career':'Engineer','name':'Fred'},'Elle':{'age':27,'name':'Elle'}}

返回值作用函数通过返回值向调用者传递处理结果或状态信息。设计原则根据函数的功能和需求设计返回值类型和结构;确保返回值清晰、准确、易于理解;在必要时使用多个返回值传递更多信息。返回值作用及设计原则找出给定范围内所有素数。原始程序将原始程序改写为函数形式,提高代码复用性和可维护性。改写目标定义函数并指定参数;实现素数判断逻辑;遍历给定范围并更新素数列表;返回素数列表。改写步骤示例:素数程序改写实践#5-8deffind_prime(m,n):prime=[]foriinrange(m,n+1):forjinrange(2,i): #j从2到i-1ifi%j==0:breakelse:prime.append(i)returnprimeprime_list1=find_prime(20,50)print(prime_list)prime_list2=find_prime(5,10)print(prime_list2)

输出:[23,29,31,37,41,43,47][5,7]

自我介绍。原始程序把介绍信息作为键、参数作为值,并返回一个表示介绍人信息的字典改写目标示例:自我介绍程序改写实践#5-9defintroduction(name,age):person={'name':name,'age':age}returnpersonperson_1=introduction('Fred',30)print(person_1)输出:{'name':'Fred','age':30}

自我介绍。原始程序让函数选择性的存储职业改写目标示例:自我介绍程序改写实践2#5-10defintroduction(name,age,career=''):person={'name':name,'age':age}ifcareer:person['career']=careerreturnpersonperson_1=introduction('Fred',30,career='Engineer')print(person_1)person_2=introduction('Elle',27)print(person_2)

输出:{'name':'Fred','age':30,'career':'Engineer’}{'name':'Elle','age':27}

自我介绍。原始程序结合使用函数introduction()和while循环,以更正规的方式保存用户信息并反馈用户改写目标示例:自我介绍程序改写实践3#5-11 """定义introduction(name,age,career='')函数"""person_list={}whileTrue:print("\nPleasetellmeyourpersonalInfo:")print("(enter'q'atanytimetoquit)")_name=input("name:")if_name=='q':break_age=input("age:")if_age=='q':break_career=input("career:")if_career=='q':break_person=introduction(_name,_age,_career)person_list[_person['name']]=_personprint("\nHello,"+_person['name']+"!YourInfohasbeensaved")

print(person_list)自我介绍。原始程序结合使用函数introduction()和while循环,以更正规的方式保存用户信息并反馈用户改写目标示例:自我介绍程序改写实践3函数嵌套调用与递归实现03函数内部调用函数概念及优势defsum3Number(a,b,c):"""求3个数的和"""returna+b+c#return的后面可以是数值,也可是一个表达式

defaverage3Number(a,b,c):"""完成对3个数求平均值"""#因为sum3Number函数已经完成了3个数的就和,所以只需调用即可#即把接收到的3个数,当做实参传递即可sumResult=sum3Number(a,b,c)aveResult=sumResult/3.0returnaveResult

"""调用函数,完成对3个数求平均值"""result=average3Number(11,2,55)print("averageis%d"%result)

输出:averageis22函数内部调用函数指在一个函数内部调用另一个函数,通过嵌套的方式实现复杂的功能逻辑。优势提高代码复用性、简化代码结构、增强程序可读性。函数内部调用函数概念及优势函数直接或间接调用自身的一种方式,通常将一个大问题分解为若干个小问题来解决。递归函数原理自我调用、必须有退出条件、可能导致栈溢出特点遍历树形结构、求解阶乘问题、斐波那契数列等。应用场景递归函数原理、特点及应用场景deff1(): print('是我') f1()f1()阶乘迭代函数实现循环结构进行累乘。示例:求阶乘迭代函数实现#迭代deffact(n):

result=1

foriinrange(2,n+1):

result*=i

returnresultfact(5)输出:120阶乘递归函数实现通过递归调用自身来计算给定数字的阶乘,每次递归将数字减1,直到数字为1时返回1作为递归结束条件。示例:求阶乘递归函数实现#递归deffact(n):

ifn==1: #递归结束条件return1else:returnn*fact(n-1)

fact(5)

输出:120示例:求阶乘递归函数实现factorial(5) #第1次调用使用5 5*factorial(4) #第2次调用使用45*(4*factorial(3)) #第3次调用使用35*(4*(3*factorial(2))) #第4次调用使用25*(4*(3*(2*factorial(1)))) #第5次调用使用15*(4*(3*(2*1))) #从第5次调用返回5*(4*(3*2)) #从第4次调用返回5*(4*6) #从第3次调用返回5*24 #从第2次调用返回120 #从第1次调用返回VS递归函数通过自我调用的方式实现循环而迭代函数则通过循环结构实现。优缺点分析递归函数代码简洁易懂,但可能导致栈溢出;迭代函数虽然代码相对复杂,但执行效率更高。递归函数与迭代函数比较递归函数与迭代函数比较分析尾递归优化将已经计算过的结果保存起来,避免重复计算记忆化技术迭代代替递归对于某些问题,使用迭代代替递归可以提高执行效率。将递归调用作为函数的最后一个操作,以便编译器或解释器进行优化性能优化策略控制递归深度通过限制递归深度来避免栈溢出。使用循环代替递归对于可能导致无限递归的问题,可以考虑使用循环结构代替递归。设置合理的退出条件确保递归函数在合适的条件下能够退出。避免无限递归方法deff1(): print('是我') f1()f1()总结回顾与拓展延伸04函数的定义函数是一段具有特定功能的代码块,可以接收输入参数并返回输出结果。在Python中,使用def关键字定义函数,指定函数名和参数列表,并在函数体内编写实现特定功能的代码。函数的调用调用函数时,需要提供函数名以及所需的输入参数(如果有的话),然后函数会执行相应的操作并返回结果。调用函数的方式是在函数名后加上括号,括号内可以包含输入参数。函数的参数传递Python中函数的参数传递采用值传递方式,即传递的是参数的值而不是变量本身。对于不可变类型(如数字和字符串),传递的是值的副本;对于可变类型(如列表和字典),传递的是对象的引用。关键知识点总结关键知识点总结函数的返回值函数可以返回任意类型的值,包括数字、字符串、列表、字典等。在函数体内使用return语句指定返回值,如果函数体内没有return语句或者return语句后没有跟任何值,则函数默认返回None。Lambda函数简介Lambda函数示例Lambda函数与高阶函数contentsLambda函数Lambda函数定义Lambda函数是一种匿名函数,使用lambda关键词定义,无需定义函数名,可以接收任意多个参数,并返回单个表达式的值。语法结构其中args是参数列表,expression是返回表达式。作用Lambda函数用于定义一个简单、可重复使用的函数,通常用于高阶函数中,如sorted(),filter(),map()等。Lambda函数简介lambda[arg1[,arg2,.....argn]]:expression示例定义一个简单的sum()函数,接受三个参数x、y、z,并返回它们的和。转换成Lambda函数将sum()函数转换成Lambda函数,只需将参数和返回值更改为所需的格式即可。运行结果运行Lambda函数,传入三个整数参数,将它们相加并返回结果。Lambda函数示例defsum(x,y,z): returnx+y+zprint(sum(1,2,3))lambdax,y,z:x+y+z#使用lambda函数

sum=lambdax,y,z:x+y+zprint(sum(1,2,3))示例利用循环和判断语句,找出列表中所有的奇数并打印转换成列表解析式利用列表解析式实现相应功能转换成Lambda函数将匿名函数与高阶函数配合,实现相应功能。Lambda函数示例#打印其中所有的奇数 numbers=[1,2,6,23,37,41,60,83,2022]odd_number=[]forninnumbers:ifn%2==1:odd_number.append(n)print(odd_number)输出:[1,23,37,41,83]#使用列表解析式odd_numbers=[iforiinnumbersifi%2==1] #使用lambda函数

print(list(filter(lambdax:x%2==1,numbers)))结合高阶函数由于Lambda函数主要在短时间内需要一个函数时才被使用,所以匿名函数常常应用于函数式编程的高阶函数中,作为参数传递给高阶函数。高阶函数以一个函数作为实际参数,并且可以返回另一个函数。sorted函数接收一个key函数来实现对可迭代对象进行自定义的排序。其调用格式为:sorted(iterable,key=None,reverse=False)其中,可迭代对象(iterable)主要是列表、字符串、元祖、集合和字典;key接受一个函数,根据此函数返回的结果,进行排序;reverse表示排序方向,默认为从小到大,reverse=True为逆向Lambda函数与高阶函数#sorted+lambdaleaders={4:"EdwardLi",2:"Tom",3:"JerryZhang",1:"Jerry"}leaders=dict(sorted(leaders.items(),key=lambdax:x[0]))print(leaders)leaders=dict(sorted(leaders.items(),key=lambdax:len(x[1])))print(leaders)输出:{1:'Jerry',2:'Tom',3:'JerryZhang',4:'EdwardLi'}{2:'Tom',1:'Jerry',4:'EdwardLi',3:'JerryZhang'} 结合高阶函数由于Lambda函数主要在短时间内需要一个函数时才被使用,所以匿名函数常常应用于函数式编程的高阶函数中,作为参数传递给高阶函数。高阶函数以一个函数作为实际参数,并且可以返回另一个函数。filter函数用于过滤序列。其调用格式为:filter(function,iterable)该函数接收一个函数和一个序列,把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。其返回的是一个迭代器对象,如果要转换为列表,可以使用list()来转换。Lambda函数与高阶函数#filter+lambdaodd=lambdax:x%2==1templist=filter(odd,[1,2,3,4,5,6,7,8,9])print(list(templist))输出:[1,3,5,7,9] 结合高阶函数由于Lambda函数主要在短时间内需要一个函数时才被使用,所以匿名函数常常应用于函数式编程的高阶函数中,作为参数传递给高阶函数。高阶函数以一个函数作为实际参数,并且可以返回另一个函数。map函数用于把一个函数应用在一个(或多个)序列上。其调用格式为:map(function,*iterables)该函数接收一个函数和一个序列,将传入的函数依次作用到序列的每个元素,并把结果作为新的序列返回。Lambda函数与高阶函数#map+lambdam1=map(lambdax:x**2,[1,2,3,4,5])print(list(m1))m2=map(lambdax,y:x+y,[1,3,5,7,9],[2,4,6,8,10])print(list(m2))输出:[1,4,9,16,25][3,7,11,15,19]作用函数还能存储在被称为模块的独立文件中,通过模块导入并被主程序使用。函数存储在独立的文件中,可隐藏代码细节,让人专注于程序的高层逻辑上,也能在多个程序中重复利用函数,实现部分功能共享。创建模块模块是扩展名为.py的文件,包含要导入到程序中的代码。下面将5-11代码拆分,先创建一个包含函数introduction()的模块,文件命名为intro.py,把introduction()程序块中的内容复制到该文件中。在intro.py所在的目录中创建另一个名为intro_list.py的文件,在该文件中导入刚创建的模块,将主程序部分内容复制到该文件中。模块导入模块具体操作详见章节1.3.2。如果想在一个模块中包含多个函数,可以使用两个空行将相邻的函数分开,方便阅读。所有的import语句都应放在文件开头,唯一例外的情形是,在文件开头使用了注释来描述整个程序。实验:递归遍历文件实验:学员管理系统contents实验实验:递归遍历文件案例描述:递归遍历指定路径下的所有文件和文件夹。案例分析:1.传入最外层文件夹路径,用Python中的listdir方法遍历路径下的文件和文件夹;2.循环中用Python中的isfile方法识别是否是文件夹。如果遍历到文件夹,继续递归调用,依次深入到最深层,从而打印出整个路径下的全部文件。实验:递归遍历文件"""递归遍历指定路径下的所有文件和文件夹"""importos #①defdisplay_File(path): #②#遍历路径下的文件和文件夹foreachinos.listdir(path): #③#得到文件的绝对路径absolute_path=os.path.join(path,each) #④#得到是否为文件还是目录的布尔值(是文件则True,是文件夹则False)

is_file=os.path.isfile(absolute_path) #⑤

#二分支选择:是文件就直接打印,是文件夹就递归ifis_file:print(each)

else:#文件夹范围开始标识

print('++++',each,'++++') #⑦display_File(absolute_path) #⑥#文件夹范围结束标识print("++++",each,"++++") #⑦

print("------递归遍历文件:--------") #⑦#需要遍历的文件夹地址:按需修改display_File(r"/Users/lihewang/Desktop/代码") #⑧实验:学员管理系统案例描述:创建一个学员管理系统。需求:进入系统显示系统功能界面,功能如下:1. 添加学员2. 删除学员3. 修改学员信息4. 查询学员信息5. 显示所有学员信息6. 退出系统案例分析:1.显示功能界面;2.用户输入功能序号;3.根据用户输入的功能序号,执行不同的功能(函数),共6个函数:显示功能界面print_info()、添加信息add_info()、删除信息del_info()、修改信息modify_info、查询信息search_info()、显示所有信息print_all()。由于退出系统实现方便,可以在主程序中直接添加代码功能,而不另外包装成函数;4.各个功能的函数定义;5.在主程序中进行函数调用。实验:学员管理系统#主程序info=[]#学员名单whileTrue:#1.显示功能界面

print_info()

#2.用户选择功能

user_num=input('请选择您需要的功能序号:')#3.根据用户选择,执行不同的功能

ifuser_num=='1':print('添加学员')add_info()elifuser_num=='2':print('删除学员')del_info()elifuser_num=='3':print('修改学员信息')modify_info()elifuser_num=='4':print('查询学员信息')search_info()elifuser_num=='5':print('显示所有学员信息')print_all()elifuser_num=='6':exit_flag=input('确定要退出吗?yesorno:')ifexit_flag=='yes':breakelse:print('输入错误,请重新输入!!!')实验:学员管理系统#显示功能界面defprint_info(): print('-'*20)print('欢迎登录学员管理系统')print('1:添加学员')print('2:删除学员')print('3:修改学员信息')print('4:查询学员信息')print('5:显示所有学员信息')print('6:退出系统')print('-'*20)实验:学员管理系统defadd_info(): """添加学员"""#接收用户输入学员信息new_id=input('请输入学号:')new_name=input('请输入姓名:')new_tel=input('请输入手机号:')

#声明info是全局变量globalinfo#检测用户输入的姓名是否存在,存在则报错提示foriininfo: ifnew_name==i['name’]: print('该用户已经存在!’) return#如果用户输入的姓名不存在,则添加该学员信息info_dict=

温馨提示

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

评论

0/150

提交评论