一、函数的定义
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) return msg # return 1,2,3,"a",["nana"],{"name":"cc"} t1=test01() print(t1) 结果: test1 test1
3)返回值>1,返回tuple
def test01(): 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样例
位置参数&关键字 def test01(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
def calc(n): print(n) if int(n/2)==0: return n res=calc(int(n/2)) return calc(10) 结果: 10 5 2 1
3.2 问路递归
person_list=["nana","CC","小小","春春"] def ask_way(person_list): print("—"*60) #打印分隔符 if len(person_list)==0: return "没人知道学校地址" person=person_list.pop(0) if person=="小小": return "%s说:我知道学校地址,地铁A口直行100m"%person print("hi 帅哥[%s],路在哪里"%person) print("%s回答道:我不知道,我帮你问%s"%(person,person_list)) time.sleep(10) res=ask_way(person_list) print("——",res) return res res=ask_way(person_list) print(res) 结果: ———————————————————————————————————————————————————————————— hi 帅哥[nana],路在哪里 nana回答道:我不知道,我帮你问['CC', '小小', '春春'] ———————————————————————————————————————————————————————————— hi 帅哥[CC],路在哪里 CC回答道:我不知道,我帮你问['小小', '春春'] ———————————————————————————————————————————————————————————— —— 小小说:我知道学校地址,地铁A口直行100m —— 小小说:我知道学校地址,地铁A口直行100m 小小说:我知道学校地址,地铁A口直行100m
四、函数作用域
函数调用与调用位置无关,只跟开始函数声明有关,跟函数作用域有关
函数调用包含两部分:函数定义部分和函数执行部分
1、函数调用样例(1)
def test1(): print("in the test1") def test(): print("in the test") return test1 res=test() #返回test1函数的内存地址 print(res()) #test1() 结果: in the test in the test1 None 因为test1无返回值,故执行此函数返回为None
2、样例(2)
NAME="alex" def foo(): name="Lhf" def bar(): name="wpq" print(name) return bar a=foo() #获取bar的内存地址 print(a) #返回bar的内存地址 a() #执行函数bar() 结果: <function foo.<locals>.bar at 0x0000029E2C204620> wpq
3、样例(3)
NAME="alex" def foo(): name="Lhf" def bar(): name="wpq" def tt(): print(name) return tt return bar 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)