一、函数的定义
1、函数的好处
1)代码重用
2)保持一致性,易维护
3)可扩展
2、函数的结构
def test(x): #def为定义函数的关键字,test为函数名,x为参数(可以带参数,也可以不带参数)
"..................."#注释:解释函数的作用,规范写法
x=x+1#泛指代码块或者程序处理的逻辑
return y #泛指返回值,可以不定义
y=test(3) #运行test这个函数
print(y)
总结:
返回值数=0,None
返回值数=函数名,返回函数返回值
返回值数=其他,返回其他
函数遇到return立马结束
2.1样例
1)没有return,函数返回值为None
def test01():
msg="test1"print(msg)
t1=test01()
print(t1)
结果:
test1
None
2)返回值=1,则返回object
def test01():
msg="test1"print(msg)returnmsg
#return 1,2,3,"a",["nana"],{"name":"cc"}
t1=test01()
print(t1)
结果:
test1
test1
3)返回值>1,返回tuple
deftest01():
msg="test1"
print(msg)return 1,2,3,"a",["nana"],{"name":"cc"}
t1=test01()print(t1)
结果:
test1
(1, 2, 3, 'a', ['nana'], {'name': 'cc'})
二、函数的参数
1、函数的形参和实参
形参:只在函数内部有效,函数调用结束返回,主调用函数后不再使用该形参变量,形参只有调用时才分配内存空间
实参:包含常量、变量、表达式和函数
def cal(x,y):#x,y为形参
res=x**y
return res
res=cal(2,3)#2,3为实参
print(res)
2、位置参数与关键字
位置参数中形参与实参必须一一对应
关键字,位置无需固定
关键字和位置参数混合使用时,位置参数必须在关键字的左边
2.1样例
位置参数&关键字deftest01(x,y,z):print(x)print(y)print(z)
test01(1,4,2) #位置参数
test01(x=3,y=4,z=8)#关键字test01(66,88,z=109)
3、默认参数
def handle (x,type="mysql"):#type="mysql"为默认函数
print(x)print(type)
handle("hello")
handle("hello","sql")
handle("hello",type="love")
4、参数组:非固定长度的参数,*列表相关,**字典相关
1)*列表相关
def handle (x,*args):# print(x)print(args)
handle(1,2,3,45,77,988)
handle(2)
handle(3,{"name":"cc","age":19})#按位置参数方式传值于形参对应的值
handle(4,*["a","xx","as"])#*转换为一个列表
结果:1(2, 3, 45, 77, 988)2()3({'age': 19, 'name': 'cc'},)4('a', 'xx', 'as')
2)**字典相关
def handle (x,**kargs):print(x)print(kargs)
handle(1,y=12,z=66)#handle(2,y=77,z=88,y=99)#一个参数y不能传两个值,会报错
结果:1{'z': 66, 'y': 12}
3)*列表相关,**字典相关组合
def handle (x,*args,**kargs):print(x)print(args)print(kargs)print(kargs,kargs.get("y"))
handle(1,2,33,445,566,xx=1,y=23,z=990)
handle(2,*[11,22,33],**{"y":7777})
结果:1(2, 33, 445, 566)
{'xx': 1, 'z': 990, 'y': 23}
{'xx': 1, 'z': 990, 'y': 23} 23
2(11, 22, 33)
{'y': 7777}
{'y': 7777} 7777
三、函数递归
1、函数递归的含义
一个函数在自己内部调用自己
2、函数递归的特性
1)必须有一个明确的结束条件,否则会无限循环
2)每次进入更深一层递归时,问题规模相比上次递归都应该有所减少
3)递归效率低,递归层次过多会导致内存溢出
3、递归样例
3.1
defcalc(n):print(n)if int(n/2)==0:returnn
res=calc(int(n/2))returncalc(10)
结果:10
5
2
1
3.2 问路递归
person_list=["nana","CC","小小","春春"]defask_way(person_list):print("—"*60) #打印分隔符
if len(person_list)==0:return "没人知道学校地址"person=person_list.pop(0)if person=="小小":return "%s说:我知道学校地址,地铁A口直行100m"%personprint("hi 帅哥[%s],路在哪里"%person)print("%s回答道:我不知道,我帮你问%s"%(person,person_list))
time.sleep(10)
res=ask_way(person_list)print("——",res)returnres
res=ask_way(person_list)print(res)
结果:
————————————————————————————————————————————————————————————
hi 帅哥[nana],路在哪里
nana回答道:我不知道,我帮你问['CC', '小小', '春春']
————————————————————————————————————————————————————————————
hi 帅哥[CC],路在哪里
CC回答道:我不知道,我帮你问['小小', '春春']
————————————————————————————————————————————————————————————
—— 小小说:我知道学校地址,地铁A口直行100m
—— 小小说:我知道学校地址,地铁A口直行100m
小小说:我知道学校地址,地铁A口直行100m
四、函数作用域
函数调用与调用位置无关,只跟开始函数声明有关,跟函数作用域有关
函数调用包含两部分:函数定义部分和函数执行部分
1、函数调用样例(1)
deftest1():print("in the test1")deftest():print("in the test")returntest1
res=test() #返回test1函数的内存地址
print(res()) #test1()
结果:inthe testinthe test1
None
因为test1无返回值,故执行此函数返回为None
2、样例(2)
NAME="alex"
deffoo():
name="Lhf"
defbar():
name="wpq"
print(name)returnbar
a=foo() #获取bar的内存地址
print(a) #返回bar的内存地址
a() #执行函数bar()
结果:.bar at 0x0000029E2C204620>wpq
3、样例(3)
NAME="alex"
deffoo():
name="Lhf"
defbar():
name="wpq"
deftt():print(name)returnttreturnbar
bar=foo() #获取bar的内存地址
tt=bar() #运行bar函数得到tt的内存地址
print(tt)
tt()#执行函数tt
或者 #foo()()()
结果:
wpq
五、匿名函数
匿名函数:lambda函数关键字:x 形参:x+1处理逻辑。组成
一般不会单独存在,处理逻辑一般是简单的表达式
2、举例
lambda x,y,z:(x+1,y+2,z+3)
f=lambda x,y,z:(x+1,y+2,z+3)
res=f(1,2,3)print(res)
结果:
(2, 4, 6)