《Python语言》电子课件-第七章_第1页
《Python语言》电子课件-第七章_第2页
《Python语言》电子课件-第七章_第3页
《Python语言》电子课件-第七章_第4页
《Python语言》电子课件-第七章_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

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

文档简介

11第7章

函数226.1字符串操作6.2正则表达式上节回顾337.1抽象与函数7.2创建函数7.3函数参数7.4变量的作用域7.5递归7.6函数修饰器7.7完成五子棋(封装及重构)本章目录44体系结构7.1抽象与函数抽象(abstraction)是一种简化复杂的实际问题的方法,它为实际问题找到准确的定义,并且可以恰当的解释问题。其中可能会忽略一些无关的细节,以便更充分地注意与当前问题有关的方面。简单的说,就是将一种复杂的活动、繁琐的流程简化为一个具体的计算机能够理解的操作。例如苹果、香蕉、生梨、葡萄、桃子等,它们共同的特性就是水果。得出水果概念的过程,就是一个抽象的过程。57.1抽象与函数所谓函数是可重用的代码段,其被允许起名字,然后通过调用该名字的方式,调用对应代码段(就是调用函数)。类似于其它语言,Python语言中采用函数实现各个功能模块,且每个函数具有特定的功能。67.1抽象与函数函数具有以下特征:(1)Python语言函数是按照一定规则书写的能完成一定功能

的代码段。(2)一个Python语言函数应该能够完成一个简单、明确和单一的功能,函数名应该能够明确表达函数的功能。这样有助于提高代码的可读性和可重用性。如果不能够给函数起一个明确、简练的函数名,那说明该函数的功能不是单一的,函数实现了多种不同的功能,这个函数就可以被拆分为若干个小函数。77.1抽象与函数函数具有以下特征:(3)Python语言程序由若干个文件组成,一个文件作为一个功能模块,完成一定功能。这样不仅便于程序的开发和管理,还能提高程序的重用性和开发效率。(4)Python语言函数之间是平行的,相互独立。函数是独立的个体。函数虽然是平行的,但是函数之间可以相互调用。(5)如果函数内没有return语句,就会自动返回None对象。(6)Python函数是引用调用,因此在函数内,对参数的改变会影响到原始对象。不过事实上只有可变对象会有影响,对不可变对象来说,它的行为类似按值调用。87.2创建函数定义函数的方法:使用def关键字,然后接函数名,在其后的小括号中填上需要的参数,函数参数是可选的(7-1中的arguments),该行要以冒号结尾。接下来是一块代码,它们就是函数体。需要注意缩进处理。9def函数名(参数):

函数体上面函数定义中,第5行是函数头,使用def关键字定义Function_name的函数,小括号中就是要传入的参数。以冒号结尾说明函数体已经开始。函数内容需要进行缩进处理。然后开始编写函数体如第6、7行。关于函数调用:Python中的调用函数方法与其它高级语言一致,为函数名加上一对小括号(括号内是函数参数)。10defFunction_name([arguments]):

'''optionaldocumentationstring'''

Function_suite例7-1如何定义函数问题分析:编写Helloworld函数,其功能是打印字符串“Helloworld”。11Hello

World!运行结果:例7-2库函数和用户自定义函数举例1'''2例

7-2库函数和用户自定函数示例3使用用户自定义函数输出Helloworld!4'''5#!/usr/bin/python6#Filename:Helloworld.py7

8#HelloWorld:用户自定义函数,功能是输出Helloworld!字符串9def

sayHello():10#调用内建函数print,输出Helloworld11print

'HelloWorld!'12

13sayHello()

#调用函数7.3函数参数所谓函数参数,就是在函数声明后的小括号中的变量。当使用函数时,在小括号中提供的值是实际参数,或者称为参数。12问题分析:定义PrintMin函数,输出两个输入参数para_a和para_b的较小值。131'''2例

7-3函数形参示例3使用用户自定义函数输出两个数的较小值!4'''5#!/usr/bin/python6#Filename:PrintMin.py7

8#PrintMin:用户自定义函数,功能是输出两个数的较小值!9def

PrintMin(para_a,para_b):10#判断参数大小11ifpara_a<para_b:12printpara_a,’isminimux’13else:14print

para_b,

'isminimux’15#调用内建函数print,输出较小值16PrintMin(2,7)#直接参数调用17a=618b=819PrintMin(a,b)

#以变量的形式提供参数2isminimux6isminimux运行结果:例7-3函数形参举例7.3.1函数参数类型形参的参数类型:必备参数命名参数缺省参数不定长参数147.3.1函数参数类型1、必备参数

必备参数需要按照参数声明的顺序如实传入函数中,如果未传入参数,或者参数数量不对应,就会出现语法错误。主要针对那些函数设计时就已经清楚了函数的各个参数及功能已经确定了。这样就可以直接定义函数体。在实际开发中,可能使用的很少,因为很少有功能参数完全确定的情况。15问题分析:定义PrintMin函数,输出两个输入参数para_a和para_b的较小值。161'''2例

7-4函数必备参数示例3使用用户自定义函数说明函数的必备参数4'''5#!/usr/bin/python6#Filename:NecPara.py7

8#PrintMin:用户自定义函数,功能是输出两个数的较小值!9def

PrintMin(para_a,para_b):10#判断参数大小11ifpara_a<para_b:12printpara_a,’isminimux’13else:14print

para_b,

'isminimux’15#调用内建函数print,输出较小值16PrintMin(2)#传入参数数量不对应17PrintMin()

#未传入参数Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:PrintMin()takesexactly2arguments(1given)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:PrintMin()takesexactly2arguments(0given)运行结果:例7-4函数必备参数举例程序分析:参数传入不同或者未传入参数,会直接报错。7.3.1函数参数类型2、命名参数

基本用法和必备参数类似,如果参数较多,无法具体对应的写出参数的顺序,可以使用命名参数的形式,按名称指定参数。避免了参数先后顺序出错,影响函数正确性的情况。17问题分析:定义PrintMin函数,输出两个输入参数para_a和para_b的较小值。181'''2例

7-5函数命名参数示例3使用用户自定义函数说明函数的命名参数4'''5#!/usr/bin/python6#Filename:NamePara.py7

8#PrintMin:用户自定义函数,功能是输出两个数的较小值!9def

PrintMin(para_a,para_b):10#判断参数大小11ifpara_a<para_b:12printpara_a,’isminimux’13else:14print

para_b,

'isminimux’15#调用内建函数print,输出较小值16PrintMin(para_b=2,para_a=3)#使用名称指定参数2isminimux运行结果:例7-5函数命名参数举例程序分析:可以通过命名参数的形式,进行参数传递。7.3.1函数参数类型3、缺省参数

调用函数时,缺省参数的值如果没有传入,就会使用默认值。这种参数适用于那种在函数声明中某些可以确定值的参数,如果不添加该参数直接使用,会调用缺省参数,也能正确的使用函数。并且这种缺省参数,在某些函数具有多个参数的使用时,可以通过不输入缺省参数来达到控制函数功能的效果,比如定义参数缺省值为None,通过判断参数缺省值达到控制程序效果。19问题分析:定义PrintMin函数,输出两个输入参数para_a和para_b的较小值。201'''2例

7-6函数缺省参数示例3使用用户自定义函数说明函数的缺省参数4'''5#!/usr/bin/python6#Filename:NamePara.py7

8#PrintMin:用户自定义函数,功能是输出两个数的较小值!9def

PrintMin(para_a,para_b=2):10#判断参数大小11ifpara_a<para_b:12printpara_a,’isminimux’13else:14print

para_b,

'isminimux’15#调用内建函数print,输出较小值16PrintMin(3,1)#未使用缺省参数17PrintMin(3)#使用缺省参数1isminimux2isminimux运行结果:例7-6函数缺省参数举例程序分析:由于有缺省参数,在未对para_b赋值时,将使用初始缺省值2,所以输出结果如上。7.3.1函数参数类型4、不定长参数

有时一个函数可能需要比声明时更多的参数。所以这时要使用不定长参数。使用方法是在变量名前加上星号(*),这样它就会存放所有未命名的变量参数。当然也可以不多传参数。这种参数主要适用于无法确定函数参数个数情况。此时使用列表的形式,进行参数的附加,达到不必修改函数的参数定义,就可以传入多个参数的目的。21问题分析:定义PrintPara函数,打印输出所有传入的参数。221'''2例

7-7函数不定长参数示例3使用用户自定义函数说明函数的不定长数4'''5#!/usr/bin/python6#Filename:UnPara.py7

8#UnPara:用户自定义函数,打印传入参数9def

PrintPara(para_a,*para_b):10#打印传入参数11printpara_a12fortempinpara_b:#遍历参数para_b获取各个数值13printtemp14

15#调用内建函数PrintPara16PrintPara(2);#使用单个参数17PrintPara(4,5,6);#使用多个参数运行结果:例7-7函数不定长参数举例程序分析:在函数参数声明时使用*para_b将接受之后的多个参数,来实现不定长参数调用。2456例7-8函数改变参数举例问题分析:定义PrintPara函数,打印输出所有传入的参数。231'''2例

7-8函数改变参数示例3使用用户自定义函数说明函数改变参数的影响4'''5#!/usr/bin/python6#Filename:ChangeNumber.py7

8#ChangeNumber:用户自定义函数,尝试改变参数9def

ChangeNumber(number):10#修改参数值11number=112print“number:”,number13#调用函数14number=215ChangeNumber(number)16print“input_number:”number运行结果:7.3.2修改参数程序分析:在函数ChangeNumber内修改了参数number,但是它没有影响到test_number变量。这是因为参数存储在局部作用域内,函数内与函数外具有相同名称的变量没有任何关系,是两个不同的变量。number:1input_number:2241'''2例

7-9函数改变列表参数示例3使用用户自定义函数说明函数改变列表参数的影响4'''5#!/usr/bin/python6#Filename:ChangeNumberList.py7

8#ChangeNumberList:用户自定义函数,尝试改变列表参数9def

ChangeNumberList(number):10#修改参数值11number[0]=112print“number:”,number13#调用函数14number=[2,2]15ChangeNumberList(number)16print“input_number:”number运行结果:例7-9函数改变参数举例程序分析:本例中变量number所绑定的列表的确改变了。其实当两个变量同时引用一个列表的时候,它们的确引用的是同一个列表,而不是副本。number:[1,2]input_number:[1,2]7.3.2修改参数这种现象其实就是参数的值传递和引用传递。所谓值传递就是当方法被调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响实际参数的值。所谓引用传递,即方法调用时,实际参数是对象(或数组),这时实际参数与形式参数指向同一个地址,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,这个结果在方法结束后被保留了下来,所以方法执行中形式参数的改变将会影响实际参数。257.3.2修改参数如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值(相当于通过“传引用”来传递对象)。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象(相当于通过“传值”来传递对象)267.4变量的作用域一个程序的所有的变量并不是在哪个位置都可以访问,访问权限决定于这个变量是在哪里赋值。变量的作用域决定了在哪一部分程序可以访问哪些特定变量。两种最基本的变量作用域如下:全局变量:定义在函数外的拥有全局作用域,全局变量可以在整个程序范围内,被自由访问。局部变量:定义在函数内部变量,拥有局部作用域(上一节提到的作用域问题),因此局部变量只能在其被声明的函数内部调用。27问题分析:定义Add函数,完成参数number_a和number_b的求和运算。281'''2例

7-10函数作用域示例3使用用户自定义函数说明局部变量和全局变量的影响4'''5#!/usr/bin/python6#Filename:Variable.py7number=0;#全局变量8#Add:用户自定义函数--求和9def

Add(number_a,number_b):10#计算两个数的和11number=number_a+number_b;#number这里是局部变量12print“Inthefunctionnumber:”,number13#调用函数14Add(1,2)15print“Outthefunctionnumber:”,number运行结果:例7-10函数作用域举例程序分析:本例中首先定义了全局变量number赋值为0,然后在Add函数中定义了另一个number变量,是局部变量,这样在函数中对number的修改并未影响到全局变量的number。这就是因为它们作用域不同。如果想要为一个定义在函数外的变量赋值,那么就得告诉Python该变量名不是局部的,而是全局的。通常使用global语句完成这一功能。Inthefunctionnumber:3Outthefunctionnumber:0问题分析:定义Add函数,完成参数number_a和number_b的求和运算,并使用global关键字更新全局变量值。291'''2例

7-11函数global语句使用示例3使用用户自定义函数说明global的使用方法4'''5#!/usr/bin/python6#Filename:GlobalVariable.py7number=0;#全局变量8#Add:用户自定义函数--求和9def

Add(number_a,number_b):10#计算两个数的和11globalnumber12number=number_a+number_b;#number这里是局部变量13print“Inthefunctionnumber:”,number14#调用函数15Add(1,2)16print“Outthefunctionnumber:”,number运行结果:例7-11函数global语句使用举例程序分析:本例中首先定义了全局变量number赋值为0,然后在Add函数中定义了另一个number变量,但是此处使用了global语句。这个number是全局的。当函数内number发生变化时,函数外的也跟着变了。Inthefunctionnumber:3Outthefunctionnumber:37.5递归程序调用自身的编程技巧称为递归(recursion)。递归做为一种算法在程序设计语言中广泛应用,它通常把一个大型复杂的问题,转化为一个与原问题相似的,且规模较小的问题来求解。递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。通常的递归函数包含:当函数直接结束时有基本的返回值。递归调用函数自身:包括一个或多个对自身函数的调用。30问题分析:设计函数Factorial计算i的阶乘,用局部静态变量result记录i的阶乘,当调用Factorial(10)时,result*=i,采用for循环,循环调用从而计算出1、2、3、4、…、n的阶乘。311'''2例

7-12函数阶乘循环实现使用示例3使用用户自定义循环函数实现阶乘的方法4'''5#!/usr/bin/python6#Filename:Factorial.py7#n阶乘的定义:n*(n-1)*(n-2)*……*18#Factorial:用户自定义函数—阶乘计算9def

Factorial(number_a):10#计算数number_a的阶乘11result=number_a12foriinrange(1,number_a):13result*=i14returnresult15#调用函数16printFactorial(10)运行结果:例7-12函数阶乘循环实现使用举例3628800问题分析:设计函数Recursion计算i的阶乘,用局部静态变量result记录i的阶乘,当调用Recursion(10)时,实际返回10*Recursion(9),采用递归调用,从而计算出1、2、3、4、…、n的阶乘。321'''2例

7-13函数递归使用示例3使用用户自定义阶乘函数说明递归的使用方法4'''5#!/usr/bin/python6#Filename:Recursion.py7#n阶乘的定义:n*(n-1)*(n-2)*……*18#Recursion:用户自定义函数—阶乘计算9def

Recursion(number_a):10#计算数number_a的阶乘11ifnumber_a==1:12return113else:14returnnumber_a*Recursion(number_a-1)15#调用函数16printRecursion(10)运行结果:例7-13函数递归使用举例36288007.6函数修饰器本节将介绍一种Python为函数设计的高级语法——修饰器。使用修饰器的目的是,对已有的函数添加一些小功能,却又不希望对函数内容有太多刚性的修改。函数修饰器以透明,动态为原则,可以灵活的为已有的函数添加一些额外的功能。Python的函数修饰器充分借鉴了函数式编程中的技巧:将需要添加功能的函数像普通对象一样作为参数传入修饰器中;将函数作为修饰器的返回值返回。33问题分析:现在已经实现了若干函数,这些函数的功能都是按照相应规则返回一段字符串。现在想为这些函数的所有输出字符串前添加一个类似“水印”的“HelloWorld_”前缀。341'''2例

7-14函数修饰器使用示例3使用用户自定义函数说明修饰器的使用方法4'''5#!/usr/bin/python6#Filename:Deco.py7defdeco(func):8defwrappedFunc():9return"HelloWorld_"+func()10returnwrappedFunc11

12@deco13deff():14return"Iamf"运行结果:例7-14函数修饰器使用举例HelloWorld_IamfIamg15defg():16return"Iamg"17

18printf()19printg()7.6函数修饰器在程序中如果有函数需要修饰器修饰,只需在函数定义前使用@加修饰器名的语法即可使用这个修饰器。在较老版本的Python中,使用修饰器的语法更接近修饰器的本质。对于下列修饰器的使用:所以说,修饰器的本质是Python解释器在发现函数调用修饰器后,将其传入修饰器中,然后用返回的函数对象将自身完全替换。351@deco2deff():3pass等同于f=deco(f)7.6函数修饰器一个函数可以被多个修饰器嵌套修饰,以完成更加复杂的功能。有时候,为了使得函数修饰器更加灵活,还可以为函数修饰器添加参数。带参的函数修饰器,需要在修饰器函数内再添加一层内嵌函数,作为对修饰器传入参数的处理。361@deco32@deco23@deco14deff():5pass等同于f=deco3(deco2(deco1(f)))问题分析:现在已经实现了若干函数,这些函数的功能都是按照相应规则返回一段字符串。现在想为这些函数的所有输出字符串前添加一个类似“水印”的前缀,具体内容由参数决定。371'''2例

7-15函数带参数的修饰器使用示例3使用用户自定义函数说明带参数修饰器的使用方法4'''5#!/usr/bin/python6#Filename:Deco_Para.py7defdeco(prefix):8def_deco(func):9defwrappedFunc():10returnprefix+func()11returnwrappedFunc12return_deco13

14@deco("second_")运行结果:例7-15带参函数修饰器使用举例second_first_Iamf15@deco("first_")16deff():17return"Iamf"18

19printf()7.7完成五子棋(封装及重构)之前的章节已经通过前面几章所学的知识实现了五子棋,下面需要用函数的知识来封装之前的五子棋游戏。记录状态函数根据前几章的代码可以将记录状态封装为一个函数:381defRecord(qipan):2who=True3whileTrue:4t=raw_input('请输入棋子位置(x,y),现在由'+('〇'ifwhoelse'乂')+'方下子:')5t=t.split(',')6iflen(t)==2:7x=int(t[0])8y=int(t[1])9ifqipan[x][y]==0:10qipan[x][y]=1ifwhoelse211who=notwho12else:13print"当前位置已有棋子,请重新下子"14else:15print"输入位置有误,请输入要下的位置,如1,1"7.7完成五子棋(封装及重构)显示棋盘函数对该功能进行封装,提供3个参数分别是(棋盘,最大行,最大列),详细代码如下391#coding:utf-82maxX=103maxY=104Qipan=[[0,0,0,0,1,0,0,2,0,0],5[0,1,2,1,1,0,2,0,0,0],6[0,0,0,0,1,1,0,2,0,0],7[0,0,0,0,2,0,0,1,0,0],8[0,0,0,1,1,1,2,0,0,0],9[0,0,0,2,0,0,0,2,0,0],10[0,0,1,2,0,2,2,0,1,0],11[0,0,0,2,0,0,0,1,0,0],12[0,0,0,0,0,0,1,1,0,0],13[0,0,0,0,0,0,0,0,0,0],]14defPrintqp(qipan,maxx,maxy):15print('〇一二三四五六七八九')16foriinrange(maxx):17printi,18forjinrange(maxy):19ifqipan[i][j]==0:20print'十',21elifqipan[i][j]==1:22print'〇',23elifqipan[i][j]==2:24print'乂',25print'\n'>>>Printqp(Qipan,maxX,maxY)7.7完成五子棋(封装及重构)棋局判胜函数由此功能可以设计一个函数isWin参数分别为(棋盘的二维数组,棋子横坐标,纵坐标),返回值为是否赢了。是为true,否为false。401defisWin(qipan,xPoint,yPoint):#判赢2globalmaxx,maxy3flag=False4t=qipan[xPoint][yPoint]5x=xPoint6y=yPoint7#横向8count=09x=xPoint10y=yPoint11while(x>=0andt==qipan[x][y]):12count+=113x-=114x=xPoint15y=yPoint16while(x<maxxandt==qipan[x][y]):17count+=118x+=119if(count>5):returnTrue20#纵向

21count=022x=xPoint23y=yPoint24while(y>=0andt==qipan[x][y]):25count+=126y-=127y=yPoint28while(y<maxyandt==qipan[x][y]):29count+=130y+=131if(count>5):returnTrue7.7完成五子棋(封装及重构)棋局判胜函数4132#/33count=034x=xPoint35y=yPoint36while(x<maxxandy>=0andt==qipan[x][y]):37count+=138x+=139y-=140x=xPoint41y=yPoint42while(x>=0andy<maxyandt==qipan[x][y]):43count+=144x-=145y+=146if(count>5):returnTrue47#\48count=049

x=xPoin50y=yPoint51while(x>=0andy>=0andt==qipan[x][y]):52count+=153x-=154y-=155x=xPoint56y=yPoint57while(x<maxxandy<m

温馨提示

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

评论

0/150

提交评论