一:闭包函数
闭:封闭,指一个嵌套函数中的内层数据。
包:用内层函数来操作外层函数得到的数据。
闭包函数的作用:间接修改数据,保护私有数据不被轻易修改。
闭包函数的必备条件:
1.必须是一个嵌套函数
2.内层数据必须操作外层函数数据(这个数据可以是变量或参数)
3.外层函数必须返回内层函数
语法:
def 外函数名():
def 内函数名():
操作代码
return 内函数名
def person():
money = 0
def work():
nonlocal money
money += 150
print(money)
return work
res = person()
res()
上述代码就是一个闭包函数的使用,在这种方式下直接调用person()函数不会出现数据,正确的表达函数方法是将外函数名赋值给一个变量,然后对这个变量进行调用,上面就是将person的返回值赋值给res,即res等同于work。
闭包函数的检测:
内函数名.__closure__
print(res.__closure__)
# (<cell at 0x0000027403AF9430: int object at 0x00007FFB270529B0>,)
下面在列举一个带有形参的闭包函数:
def process(a):
def product():
a()
print('加一个鸡腿')
return product
def food():
print('吃了一碗大米')
food = process(food)
food()
注意:process是一个可以给函数加功能的函数。具体用法下面讲。
在上述代码中,a()就是形参调用,即调用即将传入的实参,a的本质是一个函数,先调用传进来的函数确保原来的功能可以使用;在调用函数时,对a的调用就是相当于将food函数进行调用,即先打印“吃了一碗大米”,再打印“加了个鸡腿”。
@process
def noodle():
print('一碗面条')
noodle()
# 一碗面条
# 加一个鸡腿
上述代码相当于一个装饰器,对process函数进行装饰。
用加了功能的函数重新赋值给原函数,原函数才是加上了对应功能的函数。
二:装饰器 wrapper
本质:是一个特殊的闭包函数
添加前提:要有闭包函数存在,要有被装饰的函数
作用:在不修改函数源代码/参数的前提下,给函数添加功能,并且可以给函数添加多个功能
优点:
1.通过间接的方式,保护私有数据不会轻易被改变,给函数加功能更安全
2.可以给一个/多个函数增加功能,更方便
使用装饰器书写注意点:
1.process是一个工具函数,作用是给一个/多个函数加功能
2.要给函数加功能,就得接受函数,a就是函数的形参
3.接受好函数后,先调用传进来的函数,确保原来的功能可以正常使用
4.调用函数后,在内存函数中添加对应的功能
5.返回内层函数
装饰器的使用方式:
函数名 = 装饰器(函数名)
food=process(food)
#用加了功能的函数重新赋值给原函数,原函数才是加上了对应的功能
food()
语法糖
@装饰器(外层函数名)
快速给下面的函数添加装饰器的功能
def talk(a):
def person():
a()
print('好好学习')
print('天天向上')
return person
@talk
def name1():
print('我是小宇同学')
name1()
@talk
def name2():
print('我是小美同学')
name2()
@talk
def name3():
print('我是小李同学')
name3()
三:带参装饰器
def talk(a):
def person(*args, **kwargs): # 不管要加功能的函数传什么类型的参数,传多少参数我都能接受
a(*args, **kwargs)
print('好好学习')
print('天天向上')
return person
@talk
def name1():
print('我是小明同学')
name1()
@talk
def name2(friend):
print(f'我是小明同学,带了一个{friend}')
name2('小张')
@talk
def name3(friend1, friend2):
print(f'我是小李同学,带了{friend1}和{friend2}')
name3('小王', '小韩')
def fun1(drink):
def fun2(*args, **kwargs):
drink(*args, **kwargs)
print('喝一打AD钙')
return fun2
@fun1
def hot_pot():
print('夏天到了要吃火锅')
hot_pot()
@fun1
def hot_pot1(beef):
print(f'夏天到了要吃火锅,涮点{beef}')
hot_pot1('牛肉')
总结;
什么情况下会用到装饰器:
一个相同的功能可能会在很多函数都会用到,这种情况就可以把函数写为装饰器
特性:
在不修改源代码的基础上,给一个/多个函数加功能
当一个相同的功能可能会在很多函数都会用到时用装饰器
四:递归
概念:函数的递归调用时函数嵌套调用的一种特殊形式,具体指在调用一个函数的过程中,直接或间接的调用本身。递归函数的本质就是函数内部自己调用自己(本质为循环)。
目前来看,一段代码的循环运行方案有两种,一种是while,for循环,另一种则是递归,递归最重要的是找到停止条件,否则python会一直开辟内存空间。下面是一个简单的递归函数运用:
def f1(n):
if n<5:
print(n)
n+=1
f1(n)
f1(0)
需要强调的一点:递归调用不应该无限的调用下去,必须在满足某种条件下结束递归调用。
递归调用的两个阶段
回溯:一层一层调用下去。
递推:满足某种结束条件,结束递归调用,然后一层一层返回。
def numbers(num):
if num == 1:
return 1
else:
return num + numbers(num - 1)
res = numbers(3)
print(res) # 输出结果为6
下一篇我将讲述迭代器与生成器,送给各位一句话:一个人前进的道路虽然孤独,但是只有忍受最为漫长的黑夜,才能拥有绝境翻盘的毅力,希望大家都能成为那一朵悬崖上傲然绽放的黑色玫瑰。
标签:功能,调用,return,函数,day8,Python,print,def From: https://blog.csdn.net/2401_88454635/article/details/144488020