Python第五章模块与函数

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

2020/3/81Python语言编程导论第五章模块与函数内容提要•概述•函数•模块•综合举例2020/3/82一、概述•Python的程序由包、模块和函数组成。•函数是一段可重用的有名称的代码。使用函数可以减少代码重复性,增加程序的模块化。通过输入的参数值,返回需要的结果,并可存储在文件中供以后使用。几乎任何Python代码都可放在函数中。Python为函数提供了强大支持。•模块是处理某一类问题的集合,模块由函数和类组成。模块和常规Python程序之间的唯一区别是用途不同:模块用于编写其他程序。因此,模块通常没有main函数。•包是一个完成特定任务的工具箱,Python提供了许多有用的工具包,如字符串处理、图形用户接口、Web应用、图像处理等。使用自带的工具包,可以提高程序开发效率、减少编程复杂度,达到代码重用的效果。2020/3/83Python的程序结构:2020/3/84说明:•Python自带的工具包和模块安装在其安装目录的Lib子目录中。•例如:Lib目录中的xml文件夹。xml文件夹就是一个包,该包用于完成XML的应用开发,xml包中包含四个子包:dom、sax、etree和parsers。文件__init__.py是xml包的注册文件,若无此文件,Python将不能识别xml包。•注意:包必须至少含有一个__init__.py文件。__init__.py文件的内容可以为空,它用于标识当前文件夹是一个包。2020/3/85二、函数1、函数的定义及调用•格式:def函数名(形参表):函数体语句序列[return表达式]#可选项,即有的函数可以没有返回值。•函数调用:函数名(实参表)•说明:–函数必须先定义,后使用;–函数名与变量名的命名规则相同,只能包含字母、数字和下划线_,且不能以数字打头。2020/3/86例5-1:定义计算圆面积的函数2020/3/87执行结果:2、函数的参数•在C、C++中,参数的传递有值传递和引用传递两种方式。Python中任何东西都是对象,所以参数只支持引用传递的方式。•Python通过名称绑定的机制,把实际参数的值和形式参数的名称绑定在一起,即把形式参数传递到函数所在的局部命名空间中,形式参数和实际参数指向内存中同一个存储空间。2020/3/88(1)按引用传递参数•向函数传递参数时,Python采用按引用传递的方式。这意味着当传递参数时,函数将使用新变量名来引用原始值。•例5-2:求任意两个数的和。2020/3/89执行结果:内存状态:•将x和y分别设置为3和4的内存状态:•x3•y4•刚调用add(x,y)后的内存状态,a和b分别指向x和y指向的值。•x3a•Y4b2020/3/810(2)默认值•函数的参数支持默认值。当某个参数没有传递实际的值时,函数将使用默认参数计算。•带默认值的参数不能位于没有默认值的参数前面。•例5-3:默认值参数示例。2020/3/811执行结果:(3)关键字参数•关键字参数有两大好处:–清晰地指出了参数值,有助于提高程序的可读性;–关键字参数的顺序无关紧要。•调用使用关键字参数的函数时,以param=value的方式传递参数2020/3/812例5-4:关键字参数示例2020/3/813课堂练习一:•课堂练习一2020/3/8143、函数的调用•函数调用执行的四个步骤:–调用程序在调用处暂停执行–函数的形参在调用时被赋值为实参–执行函数体–函数被调用结束,给出返回值2020/3/815例5-5:生日歌程序2020/3/816调用过程:2020/3/8174、函数的返回值•return语句:程序退出该函数,并返回到函数被调用的地方•return语句返回的值传递给调用程序•Python函数的返回值的形式:–没有返回值–返回一个值–返回多个值2020/3/818(1)无返回值的return语句等价于returnNone•等价于:2020/3/819(2)返回值可以是一个变量,也可以是一个表达式•等价于:2020/3/820(3)使用return语句返回多个值•例5-6:计算两个数的加法和减法2020/3/821说明:•eval()函数功能十分强大,其基本功能为:将字符串str当成有效的表达式来求值并返回计算结果。•例如:2020/3/8225、函数的嵌套•C、C++都支持函数的嵌套调用,Python不仅支持函数的嵌套调用,还支持函数的嵌套定义。•当然,尽量不要在函数内部定义函数,这种方式不便于程序维护,容易造成逻辑上的混乱,且嵌套定义的函数层次越多,程序维护的代价就越大。•例5-7:分别使用函数的嵌套调用、函数的嵌套定义以及函数嵌套定义时直接引用外部函数的变量等三种方式,计算表达式(x+y)*(m-n)的值。2020/3/823嵌套调用函数:2020/3/824func()sub(a,b)add(a,b)嵌套定义函数:2020/3/825嵌套定义函数示意图:add(a,b)sub(a,b)func()函数嵌套定义,内部函数直接引用外部函数的变量:2020/3/826add(a,b)sub(a,b)func()xymn嵌套定义函数,直接引用外部函数的变量示意图:6、局部变量和全局变量(1)局部变量•局部变量是只能在函数或代码块内使用的变量。•函数或代码段一旦结束,局部变量的生命周期也就结束。•局部变量的作用范围只在其被创建的函数内有效。2020/3/827例5-8:局部变量应用2020/3/828此时已超出local变量的作用范围(2)全局变量•全局变量是能够被不同的函数、类或文件共享的变量。•在函数之外定义的变量都可以称为全局变量。•全局变量可以被文件内部的任何函数和外部文件访问。•全局变量通常在文件的开始处定义。2020/3/829例5-9:全局变量应用2020/3/830运行结果:如果没有global呢?全局变量使用注意事项:(1)统一管理全局变量•可以将全局变量放到一个专门的文件中,便于统一管理。•gl.py•运行结果:2020/3/831例5-10:2020/3/832(2)慎用全局变量•应该尽量避免使用全局变量。因为不同的模块都可以自由地访问全局变量,可能会导致全局变量的不可预知性。•对于上例中gl.py中的全局变量,若程序员甲修改了_a的值,程序员乙同时也要使用_a,此时就可能导致程序的错误。这种错误是很难发现和更正的。•全局变量降低了函数或模块之间的通用性,不同的函数或模块都要依赖于全局变量。同样,全局变量降低了代码的可读性,阅读程序者并不知道调用的某个变量是全局变量。2020/3/833课堂练习二:•课堂练习二2020/3/8347、递归函数(1)递归的概念•递归函数可以在函数主体内直接或间接地调用自己,即函数的嵌套是函数本身。•递归是一种程序设计方法,使用递归可以减少重复的代码,使程序变得简洁。•递归的过程分为两个阶段:递推和回归。•递归函数的原理:–第一阶段,递归函数在内部调用自己。每一次函数调用又重新开始执行此函数的代码,直到某一级递归程序结束。–第二阶段,递归函数从后往前返回。递归函数从最后一级开始返回,一直返回到第一次调用的函数体内。即递归函数逐级调用完毕后,再按相反的顺序逐级返回。2020/3/835(2)递归的实现•一个问题能否用递归实现,看其是否具有下面的特点:–需有完成任务的递推公式。–结束递归的条件。•编写递归函数时,程序中必须有相应的语句:–一个递归调用语句。–测试结束语句。先测试,后递归调用。2020/3/836例5-11:用递归方法求n!•递归公式:1n=1n!=n*(n-1)!n1•例如,使用递归计算5!的过程:2020/3/837源程序及执行结果:2020/3/838执行结果:例5-12:编程求出Fibonacci数列的第n项•Fibonacci数列定义如下:1当n=1时F(n)=1当n=2时F(n-1)+F(n-2)当n2时•假定求出第八项。•分析:Fibonacci数列的计算具备递归的条件。首先有递推公式F(n)=F(n-1)+F(n-2),第二有结束递归的条件即n=0或n=1时不再递归。2020/3/839源程序及执行结果:2020/3/840执行结果:2020/3/841(3)递归的评价与消除递归•递归程序虽然易读、易编,但需要占用额外的内存空间,并且执行速度也受影响。•是否利用递归编程要看实际问题,如果要节约内存就用循环语句实现。若对内存要求并不高,可以用递归编程。•如果不用递归程序很难实现,则只能选择递归算法。7、lambda函数•Lambda函数用于创建一个匿名函数,函数名未和标识符进行绑定。•使用lambda函数可以返回一些简单的运算结果。•格式:lambda变量1,变量2…:表达式•功能:通常lambda赋值给一个变量,变量即可作为函数使用;也可以把lambda直接作为函数使用。2020/3/842例5-13:用lambda函数改造例5-7-3。2020/3/843执行结果:例5-14:使用lambda定义求绝对值的匿名函数2020/3/844执行结果:6、Generator函数•Generator函数的作用是一次产生一个数据项,并把数据项输出。•格式:def函数名(参数列表):…yield表达式•说明:Generator函数的定义与普通函数的区别只是在函数体内使用yield生成数据项。Generator函数可以被for循环遍历,且可以通过__next__()方法(Python2是next方法)获得yield生成的数据项。2020/3/845例5-15:用三种方法求斐波那契(Fibonacci)数列的前N项•方法一:简单输出斐波那契数列前N项2020/3/846执行结果:说明:•结果没有问题,但直接在fab函数中用print打印数字会导致该函数可复用性较差,因为fab函数返回None,其他函数无法获得该函数生成的序列。•要提高fab函数的可复用性,最好不要直接打印出数列,而是返回一个list(Python中的数据结构之一,是序列之一,由一组元素组成,值可改变。后续详细介绍)2020/3/847方法二:定义一个函数,返回一个列表,列表中包含了斐波那契数列前N项2020/3/848执行结果:方法三:使用yield2020/3/849执行结果:说明:•方法三与方法一相比,仅仅把printb改为了yieldb,就在保持简洁性的同时获得了iterable的效果。•也可以手动调用fab(5)的__next__()方法,这样可以更清楚地看到fab的执行流程。•当函数执行结束时,generator自动抛出StopIteration异常,表示迭代完成。在for循环里,无需处理StopIteration异常,循环会正常结束。2020/3/850课堂练习三:1、编写一个函数iterPower(base,exp),用迭代的方式求baseexp2、编写一个函数recurPower(base,exp),用递归的方式求baseexp2020/3/851三、模块•模块实际上是将一组函数放在一起共享公共的主题;•将这些函数存储于一个.py文件中;•使用import命令导入。2020/3/8521、模块的创建及导入•创建模块,即创建一个.py文件,在其中包含用于完成任务的变量、类和函数,不包括main函数。•模块使用之前要导入该模块,导入方法之前已做过介绍。•例5-16:创建模块,用于在屏幕上打印各种形状。2020/3/853定义的模块shapes及使用模块的源程序:2020/3/854执行结果:2020/3/855例5-17:创建一个求圆面积、圆周长、圆表面积和圆体积的模块2020/3/856确认将此代码保存为名称为circle.py的文件调用方式一:2020/3/857调用方式二:2020/3/8582、模块的属性•模块有一些内置属性,用于完成特定的任务。•例5-16中的dir(shapes),就输出了模块shapes的属性。•如:–__doc__:模块中用于描述的文档字符串–__name__:模块名–_

1 / 110
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功