Python程序设计基础(第2版)课件 第3章 函数_第1页
Python程序设计基础(第2版)课件 第3章 函数_第2页
Python程序设计基础(第2版)课件 第3章 函数_第3页
Python程序设计基础(第2版)课件 第3章 函数_第4页
Python程序设计基础(第2版)课件 第3章 函数_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

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

文档简介

第3章函数内置函数函数式编程函数的定义与调用函数的参数传递3.13.23.33.4递归函数与递归算法函数文档测试函数注释模块化程序设计3.53.63.73.8学习引导…了解…理解…掌握…运用3.1内置函数3.1内置函数Python解释器提供的一组已经实现好的函数可以直接在代码中使用,无须额外导入或安装提供基本操作和功能简化编程任务增强代码可读性提高代码性能促进代码重用3.1内置函数入门函数input()print()help()id()type()

数学函数sum()abs()max()min()pow()divmod()round()数值类型函数int()bin()oct()hex()bool()float()complex()数据类型函数range()tuple()list()set()frozenset()dict()str()序列函数len()sorted()all()any()

迭代器函数zip()map()iter()filter()enumerate()reversed()

对象操作函数format()eval()open()chr()ord()dir()

常用内置函数:3.2函数式编程3.2函数式编程命令式编程主流编程范式函数式编程开发阶段可变变量函数设计变量修改执行阶段函数求值函数组合并行执行顺序执行状态演进不可变对象流程控制函数式编程

#命令式编程 ls=

['0','1','2','3','4']

foriinrange(5): ls[i]

=

int(ls[i])

print(ls)

#[0,1,2,3,4]3.2

#函数式编程

print(list(map(int,['0','1','2','3','4'])))

#[0,1,2,3,4]将列表中的元素转换为整数的操作,命令式编程与函数式编程如下:3.3函数的定义与调用3.3函数的定义与调用——函数定义函数:用于进行某种计算或具有某种功能的有名称的一系列语句的组合。函数定义格式:def

函数名(参数):

"""文档注释"""

函数体语句

return

返回值函数的定义与调用——函数定义3.3def

函数名(参数):

"""文档注释"""

函数体语句

return

返回值函数头:def…:

首行以def关键字起始,英文冒号结束函数名符合规范的名字符合命名规则,字母、下划线和数字组成应具有一定含义read_file()、get_data()能简单说明函数的功能参数(形式参数)可传入0个或多个参数def

函数名(参数):

"""文档注释"""

函数体语句

return

返回值函数的定义与调用——函数定义3.3函数体:相当于

def缩进一档文档注释函数功能注释三对双引号引起来包括该函数的功能、可接受参数的个数和数据类型、返回值的个数和类型等函数体语句实现函数功能的一条或多条程序语句def

函数名(参数):

"""文档注释"""

函数体语句

return

返回值函数的定义与调用——函数定义3.3return返回值关键字。return是函数在调用过程中执行的最后一个语句。每个函数可以有多个return语句,但在执行过程中,只能有一个被执行到return语句不存在时,此时函数的返回值为None返回值将函数的处理结果返回给调用处返回值没有类型限制,也没有个数限制返回值为多个时,以元组形式返回3.3函数的定义与调用——函数调用

def

add_numbers(a,b): """这个函数接受两个数字参数,计算并返回它们的和。""" result=a+b

returnresult #主程序,不缩进,对def对齐 sum_result=

add_numbers(3,5)

print(sum_result)

#输出8Python遵循先定义后使用的规则程序中定义的函数只有在被调用时才运行。定义好的函数可以通过名字调用。3.3函数的定义与调用——函数调用函数被调用时,要传入与函数定义里相同数量的参数传入的参数称为实际参数,必须具有确定的值。这些值会被传递给函数定义中的形式参数,相当于一个赋值的过程。

def

f(x,y): """接收2个参数x和y,返回其整数商和模""" a=x//y #计算x除以y的商 b=x%y #计算x对y取模的结果

returna,b num1,num2=f(13,3)

print(num1,num2)#输出计算结果:4,1

print(f(13,3))

#可将函数作为print函数的参数,直接输出函数的返回值3.3函数的定义与调用——函数调用return语句可以同时返回多个值以元组形式同时返回多个值,表示元组的括号可以省略

def

f(x,y): """接收2个参数x和y,返回其整数商和模""" a=x//y b=x%y

return

a,b#以元组类型(a,b)将整商和模返回给调用处

num1,num2=f(13,3)

#将返回值(4,1)中的元素按顺序赋值

print(num1,num2)

print(f(13,3))#输出5+3=83.1计算并输出球的表面积和体积

3.1计算并输出球的表面积和体积

importmath

defsphere_properties

(r):

"""

接收球的半径,计算并返回球的表面积和体积

参数:r--球的半径;返回值:返回输出球的表面积和体积

"""

surface_area=4*math.pi*r**2#计算球的表面积

volume=4/3*math.pi*r**3#计算球的体积

returnsurface_area,volume#返回2个计算结果

r=float(input())#输入球的半径和圆周率,例如5.6

#调用函数计算球的表面积和体积,函数返回值同步赋值给变量s和v

s,v=sphere_properties

(r)#调用函数,返回2个计算结果

print(f"球的表面积为:{s:.2f}")#球的表面积为:394.08

print(f"球的体积为:{v:.2f}")#球的体积为:735.29实例函数需要参数调用时传递参数函数有多个返回值以元组形式返回,括号可以省略3.4

函数的参数传递3.4参数传递当函数的定义中存在多个参数时,其参数传递形式主要有以下五种:3.4.1位置传递位置固定,参数传递时按照形式参数定义的顺序提供实际参数。优点:使用方便缺点:当参数数目较多时,函数调用容易混淆。

def

fun(name,city,hobby): """接收用户名、城市和爱好,返回一个字符串"""

return'我的名字是{name},来自{city},爱好是{hobby}。' user_name,user_city,user_hobby=input().split()

#输入:夏琪武汉羽毛球

print(fun(user_name,user_city,user_hobby)) #我的名字是夏琪,来自武汉,爱好是羽毛球。 #调用时user_name,user_city,user_hobby的值顺序传递给name,city,hobby3.4.2关键字传递提供实际参数对应的形式参数名称,根据每个参数的名称传递参数,关键字并不需要遵守位置的对应关系。优点:明确实际参数和形式参数的对应关系,参数书写顺序更灵活缺点:增加了函数调用时的代码书写量

def

fun(name,city,hobby): """接收用户名、城市和爱好,返回一个字符串"""

return'我的名字是{name},来自{city},爱好是{hobby}。' user_name,user_city,user_hobby=input().split()

#切分字符串,分别赋值

print(fun(hobby=user_hobby,city=user_city,name=user_name)) #关键字传递时顺序无关

3.4.2关键字传递——混合使用关键字传递和位置传递混用时,按位置传递的参数要出现在按关键字传递的参数前面。否则,编译器无法明确知道除关键字以外的参数出现的顺序。

def

fun(name,city,hobby): """接收用户名、城市和爱好,返回一个字符串"""

return'我的名字是{name},来自{city},爱好是{hobby}。' user_name,user_city,user_hobby=input().split()

#切分字符串,分别赋值

print(fun(user_name,city=user_city,hobby=user_hobby))

#位置参数要在关键字参数前3.4.2关键字传递——强制参数类型Python3.8之后的文档中斜杠/:其前的参数必须使用位置参数的形式星号*:其后的参数必须为关键字参数的形式divmod(x,y,/)

#斜杠前面只能是位置参数sum(iterable,/,start=0)

#斜杠前面是位置参数,不限制后面参数形式max(iterable,*[,key,default])

#星号后参数必须为关键字参数的形式sorted(iterable,/,*,key=None,reverse=False)

#斜杠前为位置参数,星号后为关键字参数3.4.3默认值传递在定义函数的时候,可以使用形如city='武汉'的方式给参数赋予默认值。默认值参数必须放在必选参数之后。在调用函数时,如果该参数得到传入值,按传入值进行计算,否则使用默认值。优点:可以降低调用函数的难度。def

fun(name,city='武汉',hobby=

'唱歌'):#默认值参数必须放在后面,且可以有多个

return'我的名字是{name},来自{city},爱好是{hobby}。'def

fun(name='夏琪',city,hobby='唱歌'):#位置参数应排在前面return'我的名字是{name},来自{city},爱好是{hobby}。’#“SyntaxError:non-defaultargumentfollowsdefaultargument”3.4.3默认值传递默认参数可指向不可变对象,如整型(int)、字符串(string)、浮点型(float)、元组(tuple)等。不能指向可变对象,如字典(dict)和列表(list)等,否则在重复调用时,可能不会创建新对象,而是对同一个对象进行操作。def

fun(name,city,hobby=

'唱歌'):#hobby使用默认值

return'我的名字是{name},来自{city},爱好是{hobby}。'user_name,user_city=

input().split()

#只输入姓名与城市2个值,输入夏琪武汉print(fun(user_name,city=user_city))

#默认值参数可以不传值#输出:我的名字是夏琪,来自武汉,爱好是唱歌。3.4.4包裹传递包裹传递也称为不定参数传递,用于在定义函数时不能确定函数调用时会传递多少个参数时使用。用*args

将多个位置参数打包成一个元组用**kwargs

将多个关键字参数打包成一个字典。函数每次调用时,传递的参数数量可以不同。3.4.4包裹传递#当传入参数是位置传递时,所有传入参数被合并成一个元组,再传递给函数。def

add(*number):

"""接收不确定数量位置传递的参数,合并为一个元组number在函数体内使用"""

print(number)

#输出传入的对象,查看参数类型,元组,形如(1,3,5,7,9)

result

=

0

#定义一个变量,用于存储求和结果

for

i

in

number:

#遍历元组中的每个元素

if

type(i)

in

(int,float):

#对参数进行了类型检查(数值型的才能求和)

result

=

result

+

i

#求和

return

result

#返回求和结果

print(add(1,3,5,7,9))

#输出25print(add(1,2,3,4,5,6,7,8,9,10))

#输出55print(add(1,2,

'hello',3.45,6))

#输出12.453.4.4包裹传递#当传入参数是关键字传递时,传入参数合并成一个字典#以参数名作为字典的键,参数值作为字典的值再传递给函数def

add(**number):"""接收不确定数量的关键字参数,合并为字典number在函数体内使用"""

print(number)

#输出字典,形如{'a':1,'b':3,'c':5}return

sum(number.values())

#对字典的值求和,返回结果

#以下为主程序,调用函数add传入不同参数,观察输出结果print(add(a=1,b=3,c=5))

#输出9print(add(m=1,n=2,o=3,p=4,q=5,i=6,j=7,k=8))

#输出363.4.5解包裹传递解包裹传递:通过“*”或“**”操作符将一个可迭代对象(如列表、元组)或字典的内容展开,并传递给函数。解包可以有效地将组合数据中的元素映射到函数的参数中。def

add(a,b,c):"""接收三个位置传递参数,返回其加和"""return

a

+

b

+

c

#对字典的值求和,返回结果

#以下为主程序,调用函数,传递参数num1

=

(1,3,5)#位置传递参数print(add(*num1))

#调用函数,传递参数,输出结果9num2

=

{'a':

1,'b':

2,'c':

3}#关键字传递参数print(add(**num2))

#调用函数,传递参数,输出结果63.5递归函数与递归算法3.5递归——递归函数递归函数:在内部调用函数本身。递归算法是将原问题不断分解为规模缩小的子问题,然后递归调用方法来表示问题的解。优点:定义简单,逻辑清晰。缺点:效率不高,而且需要注意防止栈溢出。一般默认递归深度在1000左右,如果递归太深,可能触发异常。3.5递归——递归算法特性1.必须有一个明确的递归终止条件,使递归在有限次调用后要进行回溯才能得到最终的结果。2.在递归的临界点应该直接给出问题的解决方案。3.每次进入更深一层递归时,问题规模相比上次递归都应有所减少或更接近于解。def

fact(n):"""接收一个正整数为参数,用递归方法计算其阶乘值并返回,返回值为整型。"""

if

n

==

1:

#当n=1时

return

1#返回1,终止函数递归调用

returnn

*

fact(n-1)#每调用一次,问题规模减小1print(fact(5))

#输出:1203.2递归求解猴子吃桃问题实例说明:猴子第一天摘下若干桃子,当即吃了一半,还不过瘾,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10

天早上想再吃时,发现只剩下一个桃子。求第一天共摘了多少个桃子。思路:前一天桃子数量是后一天桃子数量加1之后再乘以2递归实现方法:定义一个递归函数peaches,接受天数n作为参数。基本情况:如果n为10,返回1。递归情况:如果n小于10,返回(peaches(n+1)+1)*2。3.2递归求解猴子吃桃问题defpeaches(days):

"""参数n为天数,递归计算桃子数量,返回第一天摘了多少个桃子"""

ifdays==10:

#递归出口,第

10

天只有

1

个桃子

return1

#第

10

天只有

1

个桃子

else:

#递归调用,第

day

天的桃子数等于第

day+1

天的桃子数加

1

再乘以

2

return(peaches(days+1)+1)*2

#peach_count(days+1)第

days+1

天的桃子数total_peaches

=peaches(1)

#调用函数计算第

1

天的桃子数量print(f"第一天共摘了{total_peaches}个桃子")

#输出:第一天共摘了1534个桃子实例3.3递归计算斐波那契数列

3.3递归计算斐波那契数列

deffibonacci(n):

"""定义递归函数,接收非负整数n,返回斐波那契数列的第n项"""

ifn

<=1:

#

前两项为0或1

returnn

else:

returnfibonacci(n

-

1)+fibonacci(n

-

2)

#

后一项等于前两项之和 num

=int(input())

#

输入非负整数

print(fibonacci(num))

#

调用递归函数求斐波那契数列的第n项并输出实例3.4汉诺塔问题实例说明:假设有三根柱子,柱子上有若干直径不同的圆盘,初始所有圆盘最开始都堆在第一根柱子上,最小的圆盘在最上面。目标是将所有圆盘从第一根柱子移动到第三根柱子。在移动过程中,每次只能移动一个圆盘。任何时候都不能将较大的圆盘放在较小的圆盘上。3.4汉诺塔问题思路:如果只有一个圆盘,直接从起始柱子移动到目标柱子如果有多个圆盘,可以将问题分解为三个子问题:先将n-1个圆盘从起始柱子移动到辅助柱子再将第n个(最大的)圆盘从起始柱子移动到目标柱子最后将n-1个圆盘从辅助柱子移动到目标柱子3.3递归计算斐波那契数列def

hanoi(n,source,helper,target):"""使用递归解决汉诺塔问题

:paramn:圆盘的数量,source:起始柱子,helper:辅助柱子,target:目标柱子"""

if

n==1:

#只剩一个圆盘时,直接从source移到targetprint(f"移动圆盘1从{source}

{target}")

else:

hanoi(n-1,source,target,helper)

#递归地将n-1个圆盘从source移到helper

print(f"移动圆盘

{n}

{source}

{target}")

#移动第n个圆盘到target

hanoi(n-1,helper,source,target)

#递归地将n-1个圆盘从helper移到targethanoi(3,

'A','B','C')

#圆盘数量为3时实例3.6函数文档测试函数文档测试在函数的文档字符串中,可以增加文档测试,检验函数的输出是否与预期相符。用引导符“>>>”加函数调用,下一行写函数预期返回值def

is_leap(year):"""接受一个年份,判断是否是闰年,返回True或False。

>>>is_leap(2000)True"""

ifyear%4==0

andyear%100!=0oryear%400==0:

returnTrue

else:

returnFalseprint(is_leap(2000))3.63.7函数注释3.7函数注释在函数参数和返回值中添加任意的元数据,方便进行文档编写、类型检查,或者是其他用途。参数的类型提示:在参数后加半角逗号和类型返回值的类型提示:在函数定义的冒号前加“->”和类型名(无返回值函数的返回值类型为None) def

greeting(name:str)

->str: """接收表示名字的字符串为参数,返回一句问候语,字符串类型。"""

return

'Hello'+name print(greeting(input()))

#以输入的名字为参数,输出问候语3.8模块化程序设计3.8模块化程序设计将大型程序划分为若干较小、独立和可复用模块的编程方法模块可以包含相关的函数、类或变量,甚至是可执行代码,负责实现特定的功能降低程序复杂性,便于代码的维护和扩展分而治之减少耦合便于协作便于测试3.8.1创建和导入模块创建模块:只需将Python代码保存为扩展名为“.py”的文件#将以下代码保存为“mymodule.py”,这个文件就是一个模块,名为“mymodule”def

greet(name):#其中包含一个greet函数,可以在其他Python文件中导入并使用

returnf"Hello,{name}!"导入模块:使用import

语句将模块导入到当前的Python文件中#假设我们有一个新的文件“test.py”,其中需要使用“mymodule”模块:import

mymodule#使用import语句可以将整个模块导入result

=

mymodule.greet("Alice")

#通过“模块名.函数名”的方式调用函数或变量print(result)

#输出:Hello,Alice!3.8.2__name__属性与模块入口每个模块都有一个特殊属性“__name__”,表示模块的名字。当模块被导入时,它的值是模块的名字当模块直接运行时,它的值是“__main__”__name__=="__main__"True:作为脚本运行False:当作模块导入def

greet(name):returnf"Hello,{name}!“if

__name__=="__main__":#比较运算结果为True

时才执行此分支下的语句块print(greet('World'))

#方便在模块内部进行功能验证,不会干扰其他模块3.8.3包的创建与使用在Python中,包是一个组织多个模块的文件夹。包的本质是一个包含有“__init__.py”文件的文件夹,可以将多个模块组合在一起,形成一个有层次结构的模块集合。有效管理和组织项目中的模块,将代码分门别类,保持代码整洁和可维护性模块Module包Package库Library3.8.3包的创建与使用——包的创建创建一个目录,这个目录将作为包的容器,包含所有相关的模块文件。在包的目录中创建一个“__init__.py”文件,告诉Python解释器这个目录应该被视为一个包,否则无法作为包被导入。#创建一个名为my_package的包

my_package/├──__init__.py└──module1.py#包含两个模块└──module2.py1#module1.py的文件内容defhello():

return

"Hellofrommodule1"2#module2.py的文件内容defgreet(name):

return

f"Hello,{name}"3#__init__.py可以为空,也可以在这里导入包中的模块,便于外部使用

from.module1importhello#从module1文件中导入hello函数from.module2importgreet#从module2文件中导入greet函数43.8.3包的创建与使用——包的使用创建好包之后,就可以在其他Python文件中导入包中的模块或包本身。import语句导入包中的模块from…

import…语句导入模块中的特定函数

importmy_package.module1

print(my_package.module1.hello())#输出:Hellofrommodule1!

frommy_package.module1importhello

print(hello())#输出:Hello

温馨提示

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

评论

0/150

提交评论