函数(三)

闭包函数

闭包,又称闭包函数或者闭合函数,其实和前面讲的嵌套函数类似,不同之处在于,闭包中外部函数返回的不是一个具体的值,而是一个函数。一般情况下,返回的函数会赋值给一个变量,这个变量可以在后面被继续执行调用。
# 闭包函数的两大特征
1.闭:定义在函数内部的函数
2.包:内部函数使用了外层函数名称空间中的名字
def outer():
x = 999
def inner():
print('from outer>>>inner',x)
return inner
x = 666
res = outer()
res() # 结果999

闭包函数的实际应用

'''闭包函数是给函数体传参的另外一种方式'''
# 函数体传参的方式有形参 闭包
# 方式1:形参
def info(username)
print(usernam)
# 函数体需要什么参数在形参在写对应的就行
info('张三')
# 方式2:闭包
def outer(username):
# username = 'jason'
def index():
print(username) # 永远使用的都是jason
return index
res = outer('kevin') # 形参username与值kevin临时绑定 >>>:outer局部名称空间中
res()
res1 = outer('jason') # 形参username与值kevin临时绑定 >>>:outer局部名称空间中
res1()

装饰器简介

装饰器是 Python 的一个重要基础部分。简单地说:他们是修改或实现其他函数的功能的函数(工具)。他们有助于让我们的代码更简短,也更能体现程序员的基础是否牢固(写的好的就是“装杯”)。大多数初学者不知道在哪儿使用它们,所以我将要分享下,哪些区域里装饰器可以让你的代码更简洁。
"""
装饰器并不是一个新的知识点 而是由前两天所有的函数知识点整合到一起的产物
名称空间 函数名 闭包函数...
"""
装饰器的本质
在不改变被装饰对象原有的'调用方式''内部代码'
的情况下给被装饰对象添加新的功能
装饰器的原则
对扩展开放
对修改封闭
# 时间戳
import time # 导入模块
# print(time.time()) # 1647568920.168808
'''上述的数字是时间戳:1970年1月1日0时0分0秒距离刚刚代码运行间隔的秒数'''
import time # 导入time模块
def outer(func_name):
def get_time(*args, **kwargs): # 可变长参数
start_time = time.time() # time.time()为时间戳 函数体开始的时间戳
res = func_name(*args, **kwargs) # 执行真正的play函数
end_time = time.time() # 函数体运行结束后的时间戳
print(end_time - start_time) # 两个时间戳的差
# 如何在此处返回真正index函数的返回值
return res #
return get_time

简易版装饰器

# 装饰器有参数的写法
def fly():
time.sleep(2) # 停止2秒
print('两秒真男人!!')
import time # 导入time模块
def outer(func_name):
def get_time(*args, **kwargs): # 可变长参数
start_time = time.time() # time.time()为时间戳 函数体开始的时间戳
func_name(*args, **kwargs) # 执行真正的play函数
end_time = time.time() # 函数体运行结束后的时间戳
print(end_time - start_time) # 两个时间戳的差
return get_time
fly = outer(fly) # 将函数作为实参赋值给
fly() # 相当于get_time()

完整版装饰器

# 有返回值的写法
def fly():
time.sleep(2) # 停止2秒
print('两秒真男人!!')
return '哈哈哈 伟啦'
import time # 导入time模块
def outer(func_name):
def get_time(*args, **kwargs): # 可变长参数
start_time = time.time() # time.time()为时间戳 函数体开始的时间戳
res = func_name(*args, **kwargs) # 执行真正的play函数
end_time = time.time() # 函数体运行结束后的时间戳
print(end_time - start_time) # 两个时间戳的差
# 如何在此处返回真正index函数的返回值
return res #
return get_time
fly = outer(fly) # 将函数作为实参赋值给
res = fly()
print(res) # 返回值: 哈哈哈 伟啦

装饰器模板

对于装饰器不太理解的其实不用太过于担心,只要记住下面的这个模板直接使用就行了
'''编写装饰器其实有一套固定的代码 不需要做任何理解'''
def outer(func_name): # func_name用于接收被装饰的对象(函数)
def inner(*args, **kwargs):
print('执行被装饰函数之前 可以做的额外操作')
res = func_name(*args, **kwargs) # 执行真正的被装饰函数
print('执行被装饰函数之后 可以做的额外操作')
return res # 返回真正函数的返回值
return inner

                            

装饰器语法糖

'''可以使代码更整洁'''
语法糖的用法就比较简单了,只要把编写好的装饰器
在函数前或某些代码前一行写 @ + 装饰器名(装饰器的外层函数的函数名)
import time # 导入time模块
def outer(func_name):
def get_time(*args, **kwargs): # 可变长参数
start_time = time.time() # time.time()为时间戳 函数体开始的时间戳
res = func_name(*args, **kwargs) # 执行真正的play函数
end_time = time.time() # 函数体运行结束后的时间戳
print(end_time - start_time) # 两个时间戳的差
# 如何在此处返回真正index函数的返回值
return res #
return get_time
# 装饰器语法糖
@outer # @ + 装饰器的外层函数的函数名
def play():
time.sleep(1) # 停止一秒钟
print('玩个寄吧游戏')
return '你给我叫爸爸!'
res = play()
print(res) # 打印返回值res 你给我叫爸爸!

装饰器修复技术

函数的装饰器修复技术,可以使被装饰的函数在增加了新的功能的前提下,不改变原来函数的函数名,还继续使用原函数的注释内容。让人很难发现是被装饰器修改过函数名。
# 做到比真的还要真 但是本质其实没有变
'''
装饰器修复技术关键在于 from functools import wraps
和 @wraps() 的连用
'''
import time # 导入time模块
from functools import wraps
def outer(func_name):
@wraps(func_name)
def get_time(*args, **kwargs): # 可变长参数
start_time = time.time() # time.time()为时间戳 函数体开始的时间戳
res = func_name(*args, **kwargs) # 执行真正的play函数
end_time = time.time() # 函数体运行结束后的时间戳
print(end_time - start_time) # 两个时间戳的差
# 如何在此处返回真正index函数的返回值
return res #
return get_time
# 装饰器语法糖
@outer # @ + 装饰器的外层函数的函数名
def play():
'''玩游戏不?'''
time.sleep(1)
print('玩个寄吧游戏')
return '你给我叫爸爸!'
# help可以查看指定函数的注释信息
help(play) # 没加前get_time(*args, **kwargs)
# 加了之后play() 玩游戏不?

posted @   Mr_胡萝卜须  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示