python实用教程-第七章-函数课件.pptx

上传人(卖家):三亚风情 文档编号:3371803 上传时间:2022-08-24 格式:PPTX 页数:47 大小:101.34KB
下载 相关 举报
python实用教程-第七章-函数课件.pptx_第1页
第1页 / 共47页
python实用教程-第七章-函数课件.pptx_第2页
第2页 / 共47页
python实用教程-第七章-函数课件.pptx_第3页
第3页 / 共47页
python实用教程-第七章-函数课件.pptx_第4页
第4页 / 共47页
python实用教程-第七章-函数课件.pptx_第5页
第5页 / 共47页
点击查看更多>>
资源描述

1、第七章 函 数 函数能够提高应用的模块性和代码的重复利用率。Python提供了许多内建函数,开发者也可以自己创建函数。Python快乐学习班的同学结束旋转乐园的游玩后,导游带领他们来到函数乐高积木厅,在函数乐高积木厅,同学们只要通过想象和创意,就可以使用手中的代码块拼凑出很多神奇的函数,它们有不带参数的,有带必须参数的,有带关键字参数的,有带默认参数的,有带可变参数的,有带组合参数的。现在陪同Python快乐学习班的同学一起进入函数乐高积木厅,开始我们的创意学习之行。7.1 函数的定义 函数这个概念在前面的章节中已经提到过很多次,也已经使用过函数。不过到目前为止,我们用的都是Python内置函

2、数。这些Python内置函数的定义部分对我们来说是透明的。因此,我们只需关注这些函数的用法,而不必关心函数是如何定义的。Python支持自定义函数,即由我们自己定义一个实现某个功能的函数。下面是自定义函数的简(1)函数代码块以def关键字开头,后接函数标识符名称和圆括号“()”。(2)所有传入的参数和自变量都必须放在圆括号中,可以在圆括号中定义参数。(3)函数的第一行语句可以选择性地使用文档字符串,用于存放函数说明。(4)函数内容以冒号开始,并且要缩进。(5)return 表达式 用于结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。单规则。Python定义函

3、数使用def关键字,一般格式如下:def 函数名(参数列表):函数体 或者更直观的表示为:def(arg1,arg2,.argN):函数的名字必须以字母开头,可以包括下画线“_”。和定义变量一样,不能把Python的关键字定义成函数的名字。函数内的语句数量是任意的,每个语句至少有一个空格的缩进,以表示该语句属于这个函数。函数体必须保持缩进一致,因为在函数中,缩进结束就表示函数结束。7.2 函数的调用 在程序设计中,函数是指用于进行某种计算的一系列语句的有名称的组合。定义一个函数时,需要指定函数的名称并写下一系列程序语句。之后就可以使用名称来“调用”这个函数。前面我们已经见过函数调用的例子,如下

4、示例:print(hello world)hello world type(hello)int(12.1)12 Python3内置了很多有用的函数,我们可以直接调用。要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs,只有一个参数。可以直接从Python的官方网站查看文档:https:/docs.python.org/3/library/functions.html 除了到Python官网查看文档,还可以在交互式命令行通过help(abs)查看abs函数的帮助信息。在交互模式下输入:help(abs)Help on built-in function abs in module

5、 builtins:abs(x,/)Return the absolute value of the argument.调用Python的函数,需要根据函数定义,传入正确的参数。函数定义时需要注意几点:(1)如果没有return语句,函数执行完毕后也会返回结果,只是结果为None。(2)return None可以简写为return。(3)在Python中定义函数时,需要保持函数体中同一层级代码的缩进一致。在一个函数中可以定义多条语句,并且在函数中能做各种赋值、运算、调用其他函数等操作,并返回结果。如可以定义输出多条语句的函数并执行(print_more.py):def print_more()

6、:print(该函数可以输出多条语句,我是第一条。)print(我是第二条)print(我是第三条)print_more()#调用函数 程序输出结果如下:该函数可以输出多条语句,我是第一条。我是第二条 我是第三条 在Python中,可以定义一个什么都不做的函数。如果想定义一个什么都不做的空函数,可以用pass语句,定义如下函数并执行(do_nothing.py):def do_nothing():pass do_nothing()pass语句什么都不做,这样有什么用呢?此处pass可以作为占位符使用,比如现在还没想好怎么写函数的代码,可以先放一个pass,让代码能运行起来。函数的目的是把一些复

7、杂操作隐藏起来,用于简化程序的结构,使程序更容易阅读。函数在调用前必须先定义。7.3 函数的参数 我们在7.1节中讲述了如何定义函数,但讲述的是定义简单的函数,还有一类函数是带有参数的,称为带参数的函数。本节将探讨如何定义带参的函数及其使用。调用函数时可以使用以下参数类型:(1)必须参数。(2)关键字参数。(3)默认参数。(4)可变参数。(5)组合参数。7.3.1 必须参数 必须参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。def param_one(str):print(the param is:,str)print(我是一个传入参数,我的值是:,str)Param_one(h

8、ello,world)代码中定义了一个必须传入一个参数的函数param_one(str),其传入参数为str,结果即是将hello,world这个值传给str。对于上面的示例,假如不传入参数或传入一个以上的参数,结果会怎样呢?操作如下:param_one()#不传入参数 程序输出结果如下:Traceback(most recent call last):File param_one.py,line 7,in param_one()#不传入参数 TypeError:param_one()missing 1 required positional argument:val_str 由输出结果可以看

9、到,程序报错:函数缺少一个必须的定位参数,参数为val_str。在实际项目应用中,若定义函数时需要定义的参数个数较少,建议定义成必须参数形式的函数。7.3.2 关键字参数 函数调用使用关键字参数来确定传入的参数值。使用关键字参数Python 解释器能够用参数名匹配参数值。def person_info(age,name):print(f年龄:age)print(f名称:name)return print(-按参数顺序传入参数-)person_info(21,小萌)print(-不按参数顺序传入参数,指定参数名-)person_info(name=小萌,age=21)print(-按参数顺序传入

10、参数,并指定参数名-)person_info(age=21,name=小萌)调用函数,输出结果如下:-按参数顺序传入参数-年龄:21 名称:小萌-不按参数顺序传入参数,指定参数名-年龄:21 名称:小萌-按参数顺序传入参数,并指定参数名-年龄:21 名称:小萌 在实际项目应用中,使用关键字参数的形式调用函数是不错的做法。7.3.3 默认参数 调用函数时,如果没有传递参数,则会使用默认参数。所谓使用默认参数,就是我们在定义函数时,给参数一个默认值,当没有给调用该函数时的该参数赋值时,调用的函数就使用这个默认的值。定义如下函数并执行(default_param.py):def default_pa

11、ram(name,age=23):print(hi,我叫:,name)print(我今年:,age)return default_param(小萌)调用函数,输出结果如下:hi,我叫:小萌 我今年:23 在一个函数定义中,是否可以定义多个默认参数?先看看以下几个函数定义的示例。(1)示例1:多个默认参数值(default_param_test.py)(2)示例2:默认参数在必须参数前(default_param_try.py)由示例1和示例2,得到如下结论。对于默认参数:(1)不管有多少个默认参数,默认参数都不能在必须参数之前。(2)不管有多少个默认参数,若不传入默认参数值,都会使用默认值。(

12、3)若要更改某一个默认参数的值,而不想传入其他默认参数,且其位置不是第一个默认参数,可以通过参数名来更改想要更改的默认参数的值。(4)若有一个默认参数是通过传入参数名更改参数值,则其他任何想要更改的默认参数都需要传入参数名来更改参数值,否则报错。(5)更改默认参数的值时,传入默认参数的顺序不需要根据定义的函数中的默认参数的顺序进行传入,不过最好同时传入参数名,否则容易出现执行结果与预期不一致的情况。7.3.4 可变参数 可变参数的基本语法如下:def functionname(formal_args,*var_args_tuple):函数_文档字符串 function_suite return

13、 expression 加了星号(*)的变量名会存放所有未命名的变量参数。如果变量参数在函数调用时没有指定参数,它就是一个空元组。我们也可以不向可变函数传递未命名的变量。如果需要一个函数能处理比当初声明时更多的参数,这些参数叫做可变参数,和前面所述两种参数不同,可变函数声明时不会命名。通过实例来说明可变函数的使用,定义如下函数并执行(person_info_var.py):def person_info_var(arg,*vartuple):print(arg)for var in vartuple:print(f我属于不定长参数部分:var)return print(-不带可变参数-)per

14、son_info_var(小萌)print(-带两个可变参数-)person_info_var(小萌,21,beijing)print(-带5个可变参数-)person_info_var(小萌,21,beijing,123,shanghai,happy)执行以上代码段,由输出结果可以看到,虽然在定义函数时只定义了两个参数,但调用时却可以传入多个参数,这和之前函数的调用不一样了,这是怎么实现的?这就是可变参数的好处,在函数内部,若在参数前加一个星号,在函数调用时,会将所有参数放在一个元组中,通过这种方式将这些值收集起来,然后供函数内部使用。如在函数person_info_var()中,参数var

15、tuple接收的是一个元组,调用函数时可以传入任意个数的参数,也可以不传。在这个示例中使用了前面所学的for循环,通过for循环遍历元组。通过这种方式定义函数,调用时是不是非常方便?我们在后续学习中会经常遇到。7.3.5 组合参数 在Python中定义函数,可以用必须参数、关键字参数、默认参数和可变关键字参数,这4种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必须参数、默认参数、可变参数和关键字参数。下面我们来介绍组合参数的使用,请看如下函数定义:def exp(p1,p2,df=0,*vart,*kw):print(p1=,p1,p2=,p2,df=,df,vart=,vart,k

16、w=,kw)exp(1,2)exp(1,2,c=3)exp(1,2,3,a,b)exp(1,2,3,abc,x=9)执行以上py文件,由输出结果可以看到,在定义exp()函数时,使用了组合参数的定义形式,Python解释器会自动按照参数位置和参数名把对应的参数传进去。对exp()函数,还可传入tuple和dict类型的参数,方式如下:args=(1,2,3,4)#args定义为tuple kw=x:8,y:9#kw定义为dict exp(*args,*kw)执行py文件,输出结果如下:p1=1,p2=2,df=3,vart=(4,),kw=y:9,x:8 由输出结果可以看到,任意函数都可以通过

17、类似func(*args,*kw)的形式进行调用,无论参数是如何定义的。7.4 形参和实参 前面已经讲述过函数的参数,本节将给大家介绍Python函数的两种类型参数,一种是函数定义里的形参,一种是调用函数时传入的实参。经常在使用一些内置函数的时候,我们需要传入参数,比如:调用math.sin时,需要传入一个整型数字作为实参,还有的函数需要多个参数,像math.pow就需要2个参数,一个是基数(base)和指数(exponent)。在函数内部,会将实参的值赋给形参,例如(basic_info.py):def basic_info(age,name):print(f年龄:age)print(f名称

18、:name)return 在basic_info()函数中,函数名basic_info后面的参数列表age和name就是实参,在函数体中分别将age和name的值传递给age和name,函数体中的age和name就是形参。在Python中,操作参数时,在函数体内的操作都是对形参的操作,不能操作实参,即在函数体中对参数的更改,是对形参的更改。内置函数的组合规则在自定义函数上同样适用。作为实参传入函数的变量名称和函数内部定义的形参的名称没有关系。函数的内部只关心形参的值,而不关心它在调用前叫什么名字。7.5 变量作用域 作用域简单说就是一个变量的命名空间。在Python中,程序的变量并不是在哪个位

19、置都可以访问的,访问权限决定于这个变量是在哪里赋值的,代码中变量被赋值的位置,就决定了哪些范围的对象可以访问这个变量,这个范围就是命名空间。变量的作用域决定了哪一部分程序可以访问哪个特定的变量名称。在Python中有两种最基本的变量作用域:(1)局部变量。(2)全局变量。7.5.1 局部变量的定义与使用 在函数内定义的变量名,只能被函数内部引用,不能在函数外引用这个变量名,这个变量的作用域就是局部的,也叫它为局部变量。变量如果在函数中是第一次出现,就称为局部变量,例如(local_var.py):def local_var():x=100 print(x)在local_var()函数中,x是在

20、函数体中被定义的,并且是第一次出现,所以x就称为局部变量。局部变量只能在函数体中被访问,超出函数体的范围访问就会报错。示例如下(local_func.py):def local_func():x=100 print(f变量x:x)print(f函数体外访问变量x:x)local_func()函数输出结果如下:Traceback(most recent call last):File D:/python/workspace/functiondef.py,line 7,in print(函数体外访问变量x:%s%(x)NameError:name x is not defined 报错提示:第7行

21、的x没有定义;由输入代码可知,第7行语句没有在函数体中,因而执行时报错了。定义如下函数并执行(func_var.py):def func_var(x):print(f局部变量x为:x)func_var(10)函数输出结果如下:局部变量x为:10 在Python中,参数的工作原理类似于局部变量,实参一旦进入函数体,就成为局部变量了。7.5.2 全局变量的定义与使用 在函数外,一段代码最始开所赋值的变量,它可以被多个函数引用,这就是全局变量。全局变量可以在整个程序范围内访问。看一个全局变量的示例(global_var.py):total_val=0#这是一个全局变量 def sum_num(arg

22、1,arg2):total_val=arg1+arg2#total_val在这里是局部变量.print(f函数内是局部变量:total_val)return total_val def total_print():print(ftotal的值是:total_val)return total_val print(f函数求和结果:sum_num(10,20)total_print()print(f函数外是全局变量:total_val)程序输出结果如下:函数内是局部变量:30 函数求和结果:30 total的值是:0 函数外是全局变量:0 全局变量可在全局使用,并且在某个函数体中更改全局变量的值,并

23、不会影响全局变量在其他函数或语句中的值。再看一个函数定义并执行的示例(func_global.py):num=100 def func_global():num=200 print(f函数体中num的值为:num)func_global()print(f函数外num的值为:num,)函数输出结果为:函数体中num的值为:200 函数外num的值为:100 虽然在文件中定义了一个名为num的全局变量,在函数func_global()的函数体中也定义了一个名为num的变量,但在函数体中使用的是函数体中的num变量,在函数体外使用num变量时使用的是全局变量的值。在函数中使用某个变量的变量值时,如果

24、该变量对应的变量名既被定义为全局变量,又被定义为局部变量,就默认使用局部变量的变量值。所以若要将全局变量变为局部变量,只需在函数体中定义一个和局部变量名称一样的变量即可。若要将函数中某个变量定义为全局变量,在需要被定义的变量前加一个关键字global即可(如func_glo_1.py示例)。在函数体中定义global变量后,在函数体中对变量做的其他操作也是全局性的(如func_glo_2.py)。7.6 函数的返回值 若定义函数时没有使用return语句,会默认返回一个None,要返回一个None,可以只写一个return,但要返回具体的数值,就需要使用return后面加上需要返回的内容。所以

25、对于函数定义来说,使用return语句可以向外提供该函数执行的一些结果。而对于函数的调用者来说,是否可以使用函数中执行的一些操作结果,就在于函数是否使用了return语句返回了对应的执行结果。在Python中,有一部分函数会产生结果,如数学函数,我们一般称这种函数为有返回值函数(fruitful function);对于另一些函数,会执行一些动作,但不返回任何值,我们称这类函数为无返回值函数。当调用有返回值函数时,可以使用返回的结果做相关操作,而使用无返回值或返回None的函数时,就只能得到一个None值。7.7 返回函数 函数可以有返回值,但除了返回值,函数中是否可以返回函数?定义如下函数(

26、calc_sum.py):def calc_sum(*args):ax=0 for n in args:ax=ax+n return ax 定义了一个可变参数的求和函数,该函数允许传入多个参数,最后返回所求得的和。定义函数如下(sum_late.py):def sum_late(*args):def calc_sum():ax=0 for n in args:ax=ax+n return ax return calc_sum sum_late()函数返回了一个之前没有看过的类型的值函数。对于此处定义的sum_late()函数,我们没有返回求和的结果,而是返回了一个求和函数。在这个例子中,在函数

27、sum_late中又定义了函数calc_sum,并且内部函数calc_sum可以引用外部函数sum_late的参数和局部变量。当sum_late返回函数calc_sum时,相关参数和变量都保存在返回的函数中,称为闭包(Closure)。在此处提到了闭包(Closure),什么是闭包呢?如果在一个内部函数里对外部函数(不是在全局作用域)的变量进行引用,内部函数就被认为是闭包。返回闭包时,返回函数不要引用任何循环变量或后续会发生变化的变量,否则很容易出现意想不到的问题。7.8 递归函数 前面刚学习了在函数中返回函数,前面也学习了可以在一个函数中调用另外一个函数,但函数是否可以调用自己呢?答案是可以

28、的,如果一个函数在内部调用自身,这个函数就称作递归函数。递归的简单定义如下:def recurision():return recursion()递归函数应该满足如下条件:(1)当函数直接返回值时有基本实例(最小可能性问题)。(2)递归实例,包括一个或多个问题最小部分的递归调用。计算阶乘n!=1 x 2 x 3 x.x n,用函数fact(n)表示,可以看出:fact(n)=n!=1 x 2 x 3 x.x(n-1)x n=(n-1)!x n=fact(n-1)x n fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理。fact(n)用递归方式定义如下(fact.py

29、):def fact(n):if n=1:return 1 return n*fact(n-1)执行以下函数:print(f调用递归函数执行结果为:fact(5)输出结果如下:调用递归函数执行结果为:120 计算fact(5)时可以根据函数定义看到计算过程:=fact(5)=5*fact(4)=5*(4*fact(3)=5*(4*(3*fact(2)=5*(4*(3*(2*fact(1)=5*(4*(3*(2*1)=5*(4*(3*2)=5*(4*6)=5*24=120 理论上,所有递归函数都可以写成循环的方式,不过循环的逻辑不如递归清晰。使用递归函数需要注意防止栈溢出。在计算机中,函数调用是

30、通过栈(stack)这种数据结构实现的。每当进入一个函数调用,栈就会加一层栈帧;每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,因此递归调用的次数过多会导致栈溢出。解决递归调用栈溢出的方法是通过尾递归优化,事实上,尾递归和循环的效果一样,把循环看成一种特殊尾递归函数也可以。尾递归是指在函数返回时调用函数本身,并且return语句不能包含表达式。这样,编译器或解释器就可以对尾递归进行优化,使递归本身无论调用多少次都只占用一个栈帧,从而避免栈溢出的情况。7.9 匿名函数 匿名函数,意即不再使用def语句这样标准的形式定义一个函数。Python使用lambda来创建匿名函数。lambda只是

31、一个表达式,函数体比def简单很多。lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。lambda 函数只包含一个语句:lambda arg1,arg2,.argn:expression 使用def语句求两个数之和示例:def func(x,y):return x+y 使用lambda表达式求两个数之和示例:lambda x,y:x+y 一般应该在如下情况下多往匿名函数的方向考虑:(1)程序一次行使用,不需要定义函数名时,用匿名函数可以节省内存中变量定义空间。(

32、2)如果想让程序更加简洁时,使用匿名函数可以做到。当然,匿名函数有几个规则要记住:(1)一般也就一行表达式,必须有返回值。(2)不能有return。(3)可以没有参数,可以有一个或多个参数。7.10 偏 函 数 偏函数是从Python2.5引入的一个概念,通过functools模块被用户调用。要注意,这里的偏函数和数学意义上的偏函数不一样。偏函数是将所要承载的函数作为partial()函数的第一个参数,原函数的各个参数依次作为partial()函数后续的参数,除非使用关键字参数。代码示例如mod_partial.py 在介绍函数的参数时,曾介绍通过设定参数的默认值可以降低函数调用的难度。从mo

33、d_partial.py示例看,偏函数也可以做到这一点。7.11 活学活用选择排序 要求:以正序(从小到大)和逆序(从大到小)两种方式输出排序结果。在开始编码之前,先了解一下选择排序的一些基本工作原理。选择排序是一种简单直观的排序算法。选择排序的工作原理如下:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余的未排序的元素中继续寻找最小(大)元素,然后放到已排序的末尾。直到所有元素均排序完毕。优点:选择排序与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,对n个元素的表进行排序只需进行

34、至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。选择排序的最优时间复杂度为O(n2),最坏时间复杂度为O(n2)。具体代码参考书中示例。7.12 技巧点拨 本章重点介绍了函数,在本章学习过程中读者逐步会发现,随着函数的使用,一个函数中的代码量也逐步增加了,代码量的逐步增加,也代表着程序出错的概率增大。在代码编写时,如果碰到一段代码不能正常工作时,可以先考虑以下3点:(1)函数获得的实参是否有问题?某个前置条件是否达到?(2)函数本身是否有问题?某个后置条件是否达到?(3)函数的调用是否有问题?函数的返回值是否正确?实际应用中要学会充分使用print()函数,该函数能帮助你清晰了解函数的执行流程。7.13 问题探讨 随着函数学习的不断深入,不知你是否有这样的疑问:为什么要有函数?定义函数的好处在哪里?7.14 7.14 章节回顾章节回顾(1)回顾函数的定义与调用。(2)回顾函数有哪些参数类型,各自有什么特点。(3)回顾形参和实参的定义与使用。(4)回顾变量的作用域有哪些,各自有什么限制。(5)回顾递归函数的定义与使用。7.15 7.15 实战实战演练演练

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(python实用教程-第七章-函数课件.pptx)为本站会员(三亚风情)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|