北京网络网站建设价格百度收录的网站多久更新一次
1.递归函数:
1.1含义:
如果一个函数在内部不调用其他函数,而是调用它本身的话,这个函数就是递归函数
1.2条件:
1.必须有一个明确的结束条件--递归出口
2.每进行更深一层的递归,问题规模相比上次递归都要有所减少
3.相邻两次重复之间有紧密的联系
1.计算1+2+3+...+100的和
def add(n):if n == 1:return 1else:return n+add(n-1)print(add(100))
2.计算斐波那契数列(1,1,2,3,5,8...)
def funa(n):if n==1 or n==2:return 1return funa(n-1)+funa(n-2)print(funa(7))
1.3优点:简洁,逻辑清晰,解题更具有思路
1.4缺点:使用递归函数的时候,需要反复调用函数,耗内存,运行效率低
2.闭包
含义:在嵌套函数的前提下,内部函数使用了外部函数的变量,而且外部函数返回了内部函数,我们就把使用了外部函数变量的内部函数称为闭包
2.1条件:
1.嵌套函数(函数里面在定义函数)
2.内层函数使用外层函数的局部变量
3.外层函数的返回值是内层函数的函数名(注意:返回函数名,而不是inner(),是因为inner函数里参数比较多或者说受到限制时,写法不太规范)
def outer():n = 10def inner():print(n)return innerprint(outer()) #<function outer.<locals>.inner at 0x000002405D04B0D8> 返回内部函数的地址
#调用内函数的第一种写法
outer()() #10
#调用的第二种写法
ot = outer() #调用外函数
ot() #调用内函数
带参数的情况
def outer(m):n = 10def inner(o):print(m+n+o)return innerouter(20)(10)ot = outer(20)
ot(10)
2.2函数引用
函数名里保存了函数所在位置的引用(就是地址)
a = 1 #a只不过是一个变量名,存的1这个数值所在的地址,就是a里面存了数值1的引用
print(a) #1
print(id(a)) #140719332688144
print(id(1)) #140719332688144a = 2 #修改a,生成新的值从新赋给变量a
print(id(a)) #140719332688176内存地址发生了改变def test(): #test也只不过是一个函数名,里面存了这个函数所在位置的引用print('这是test函数')
test()
print(test) #内存地址(引用)<function test at 0x0000017B51DC2F78>
te = test
te() #通过引用调用函数
2.3每次开启内函数都在使用同一份闭包变量
总结:使用闭包的过程中,一但外函数被调用一次,返回了内函数的引用,虽然每次调用内函数,会开启一个函数,执行后消亡,但是闭包变量实际上只有一份,每次开启内函数都在使用同一份闭包变量。
def outer(m):print("outer函数中的值",m)def inner(n):print("inner函数中的值",n)return m+nreturn innerot = outer(10)
print(ot(20)) #30
print(ot(50)) #60
print(ot(80)) #90
3.装饰器
3.1.含义:
装饰器本质上是一个闭包函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
3.2.作用:在不改变原有代码情况下给函数添加额外的功能
3.3.条件:
1.不修改源程序或函数的代码
2.不改变函数或程序的调用方法
不用装饰器的方式添加新的功能1.直接添加,2.引入参数
def test1(fn):print("读书")print("吃饭")fn()
def test2():print("看电视")
test1(test2)
3.4标准版装饰器
将原有函数名重新定义为以原函数为参数的闭包
#被修饰的函数
def send():print("发短信")def outer(fn): #外层函数,fn是形参def inner(): #内函数print("登录")fn() #send() 执行被修饰的函数return innerprint(outer(send)) #内层函数地址
outer(send)() #调用内层函数
3.5语法糖
格式:@装饰器名称
def outer(fn): #外层函数,fn是形参def inner(): #内函数print("登录")fn() #send() 执行被修饰的函数return inner@outer #注意装饰器名称后面不要加上(),前者是引用,后者是返回该函数要返回的值(最好顶格写不要空行)
def send():print("发短信")
send() #登录 发短信@outer
def send2():print("刷抖音")
send2() #登录 刷抖音
3.6被装饰的函数有参数
3.6.1标准版:
def outer(fn): #外层函数,fn是形参def inner(name): #内函数print(f"{name}是inner中的参数")fn() #func() 执行被修饰的函数return innerdef func():print("这是被装饰函数")print(outer(func)) #内层函数地址
outer(func)('panda') #调用内层函数def outer(fn): #外层函数,fn是形参def inner(name): #内函数print(f"{name}是inner中的参数")fn(name) #func() 执行被修饰的函数return innerdef func(name):print("这是被装饰函数")print(outer(func)) #内层函数地址
outer(func)('panda') #调用内层函数
3.6.2语法糖
def outer(fn): #外层函数,fn是形参def inner(name): #内函数print(f"{name}是inner中的参数")fn(name) #func() 执行被修饰的函数return inner@outer
def func(name):print("这是被装饰函数")func('panda')
3.7被装饰函数有可变参数*args ,**kwargs
def outer(fn): #外层函数,fn是形参def inner(*args,**kwargs): #内函数print("登录")fn(*args,**kwargs) #func() 执行被修饰的函数return innerdef func(*args,**kwargs):print(args)print(kwargs)print(outer(func)) #内层函数地址
ot = outer(func) #调用外层函数
ot('panda',friend='monkey',name='bear') #登录 ('panda',) {'friend': 'monkey', 'name': 'bear'}
*args:接收元组的形式,**kwargs:接收字典的形式
3.8多个装饰器
多个装饰器的装饰过程,离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰,由内到外的装饰过程
def deco1(fn):def inner():return "lucky "+fn()+" day"return inner
def deco2(fn):def inner():return "good "+fn()+" study"return inner@deco1
@deco2
def test():return "学python"
print(test()) #lucky good 学python study day@deco2
def test():return "学python"
print(test()) #good 学python study@deco2
@deco1
def test():return "学python"
print(test()) #good lucky 学python day study