5 函数
5.1 函数的定义和调用
函数的定义解决了两个问题,复用性,封装,定义成函数之后,再调用函数来实现代码的复用。
5.1.1 定义函数的语法格式:
def 函数名():
封装的代码(调用函数执行的代码)
例:def addition():
print(1+1)
5.1.2 调用函数语法格式:直接输入函数名
函数名()
addition()——2
5.1.3 调用函数有两种状态:
有返回值:执行封装的代码,并返回return关键字后面的内容,如果我们之后还需要对这个函数执行的结果进行操作,我们就使用return返回它的结果。
例:def funb():
return 1+1 #返回值
resb = funb()
print(resb)——2
没有返回值:执行封装的代码
例:def funa():
1+1
resa = funa()
print(resa)——None
5.2 函数参数
参数:我们会把可能需要改变的值定义为参数(本质就是变量)。
例:def funa(a,b):
return a+b
res = funa(10,1) #把10赋值给a,把1赋值给b
print(res)——11
三种参数:必备参数、默认参数和不定长参数
5.2.1 必备参数: 直接写变量名就是必备参数,x,y,调用时必须传入。
5.2.2 默认参数: 具有默认值的参数,调用可以不传入,不传入时默认使用默认值,传入就是你写入的值。
5.2.3 不定长参数: 可以传入任意个数的值,可以传入也可以不传入,主要有元组和字典两种类型,不传入时默认为空元组和空字典。
传入形式:
元组:*参数名,会将传入的参数放入元组
字典:**参数名,会将传入的参数放入字典,注意,字典只能定义在最后,否则会报错。
字典传入时,必须是键值对的形式,且只能最后传入,定义时也只能放在最后面。
参数传入顺序:
必备参数,默认参数,不定长参数
例:def func(x,y=10,*args,**kwargs) -> None: #->None 表示这个方法没有返回值,相当于文本的作用
print(x)
print(y)
print(args)
print(kwargs)
func(1,20,30,40,50,a=100,b=20)
——1
20
(30, 40, 50)
{'a': 100, 'b': 20}
5.2.4 文档功能
def func(x,y=10,*args,**kwargs) -> None:
->后面跟的是返回值类型,None表示没有返回值,类型有 int str bool
例:def funca(x,y) -> int: #有返回值,返回int类型
return x+y
resa = funca(10,10) #因此要赋给变量保存
resa+=10
print(resa)——30
5.2.5 拆包
拆包:类似于我们之前讲的元组拆包,在传入时也可以通过解包来传入不定长参数。
例:def func(x,y=10,*args,**kwargs): args->元组; kwargs->字典
print(x)
print(y)
print(args)
print(kwargs)
ta=(1,2,3,4)
dd={'a':100,'b':200}
func(100,20,*ta,**dd)
——100
20
(1, 2, 3, 4)
{'a': 100, 'b': 200}
5.3 函数作用域
例:
var = 100 # 全局变量
def func():
print(var) #函数内部可以访问外部的变量
func()——100
例:def funca():
vara = 200 # 函数内部定义的变量(局部变量),外面不能够访问
funca()
print(vara)——报错
5.3.1 全局作用域
要想访问函数内部定义的变量,则可使用global关键字进行全局变量申明。
注意:函数内外名字要一致,否则就是一个新变量
例:var = 100
li = [1,2]
def func():
global var # 使用global关键字
var += 10
li.append(3) # 列表可以进行修改
print(li)
print(var) #函数内部可以访问外部的变量,不能修改传入不可变对象的值,但是可变对象可以修改,列表是可变的
——[1, 2] 100
5.3.2 局部作用域
如果是嵌套的函数,则不能使用global,需要使用nonlocal 关键字。
例:def func():
print('f')
varf = 100
def func_sun():
print('sun')
nonlocal varf
varf += 10
print(varf)
func_sun()
func()—— f sun 110
5.3.3 闭包
作用:可以在外部修改函数内部的变量值,是函数内部与外界沟通的桥梁。
当数据不能由外部人员随意修改,需要把数据保护起来,要修改只能通过调用指定的函数时就涉及到闭包。
比如游戏中的血量,是不能任何地方都可以随便修改的,否则随便一个外挂就无敌了,因此需要把血量保护起来,不能随便修改,要修改只能通过调用指定的函数才行,这样就在一定程度上保护了血量。
例:def boold():
blood_olume = 100#局部变量
## 操作血量
def boold_change(live=0):
nonlocal blood_olume
blood_olume += live
return blood_olume
return boold_change
boold_change = boold()#保存的是返回的blood_change
print(boold_change(-20))——80
因为我们要保护血量,所以我们将血量定义为局部变量,这样外面就没有办法访问了。
5.4 递归函数和匿名函数
5.4.1 递归函数
函数内部调用自己,和while循环类似,需要有条件控制语句,否则就一直调用自己。
例:求5的阶乘
def func(n):
if n <= 1:
return 1
else:
return n*func(n-1) #5*func(5-1)*func(4-1)...1
res = func(5)
print(res) ——120
注意:return有两个作用,第一个作用,结束方法,第二个作用,返回我们想要的值
例:def func():
print(1)
return 1
print(2)
res =func()
print(res)——1 1
进行多次相同情况的运算时,用递归
例:5的阶乘
x = 1
res = 1
while x <= 5:
res *= x
x += 1
print(res)
8的阶乘
x1 = 1
res1 = 1
while x1 <= 8:
res1 *= x1
x1 += 1
print(res1)
递归:
def recursion(n):
if n <= 1:
return 1
else:
return n * recursion(n-1)
print(recursion(5))
print(recursion(8))
5.4.2 匿名函数
匿名函数就是没有函数名的函数,主要用来定义那种不是特别复杂的函数,常用于函数的参数中。自带返回,不用return。
匿名函数的语法规则:lambda 参数,参数...:执行的内容
例:def add(x,y):
return x+y
res = add(10,5)
print(res)——15
————>
add_lambda = lambda x,y:x+y
print(add_lambda(10,20))——3
例:add_lambda = lambda x=3,y=6 : x+y
print(add_lambda(20))——26
print(add_lambda(12,22))——34
例:字符串排序
li = [2,'a',1,'b','9',5]
li.sort(key=lambda x:str(x))
print(li)——[1, 2, 5, '9', 'a', 'b']