Python 闭包函数和装饰器
闭包函数定义:
- 基于嵌套函数
- 如果在一个内部函数里,对在外部作用域(嵌套变量)的变量进行引用,那么内部函数就被认为是闭包函数。
- Python 变量作用域 LEGB,具体参考 Python 变量作用域章节
- 闭包中外部函数返回的不是一个具体的值,而是一个函数。一般情况下,返回的函数会赋值给一个变量,这个变量可以在后面被继续执行调用。
def outer(): x = 10 def inner(): # 条件一:inner这是一个内部函数 print(x) # 条件二:引用外包环境的一个变量(但不是全局变量) return inner # 结果:inner是一个闭包函数 f = outer() f() # 结果:10
装饰器的定义:
- 它是一种函数的函数,因为装饰器传入的参数就是一个函数,然后通过实现各种功能来对这个函数的功能进行增强。
在哪里用装饰器:
- 装饰器最大的优势是用于解决重复性的操作,其主要使用的场景有如下几个:
- 计算函数运行时间
- 给函数打日志
- 类型检查
- 如下实例,我需要实现一个打印出函数 fun_one/fun_two/fun_three 中代码 sleep 的执行时间,这么写的话虽然功能可以实现,但是代码的冗余程度非常大
from time import time, sleep def fun_one(): start = time() sleep(1) end = time() cost_time = end - start print("func one run time {}".format(cost_time)) def fun_two(): start = time() sleep(1) end = time() cost_time = end - start print("func two run time {}".format(cost_time)) def fun_three(): start = time() sleep(1) end = time() cost_time = end - start print("func three run time {}".format(cost_time))
- 使用装饰器的方法简化后如下
def run_time(func): def wrapper(): # 此时的 wrapper 就是一个闭包函数 start = time() func() # 函数在这里运行 end = time() cost_time = end - start print("func run time {}".format(cost_time)) return wrapper @run_time # 这里的装饰器会将函数名称 fun_one 传入到 上面的 run_time 函数中,从而执行 def fun_one(): sleep(1) @run_time def fun_two(): sleep(1) @run_time def fun_three(): sleep(1)
- 在功能函数中加上参数
from time import time, sleep def run_time(func): def wrapper(a, b): # 此时的 wrapper 就是一个闭包函数 start = time() func(a, b) # 函数在这里运行 end = time() cost_time = end - start print("func run time {}".format(cost_time)) return wrapper @run_time # 这里的装饰器会将函数名称 fun_one 传入到 上面的 run_time 函数中,从而执行,fun_one = run_time(fun_one) def fun_one(a, b): print(a) print(b) sleep(1) fun_one("hello", "world")
- 带参数的装饰器
from time import time, sleep def logger(msg): # 在此处多加一个装饰器参数 def run_time(func): def wrapper(*args, **kwargs): start = time() func(args, kwargs) end = time() cost_time = end - start print("func_{} run time {}".format(msg, cost_time)) return wrapper return run_time @logger(msg="One") def fun_one(a, b): print(a + b) sleep(1) @logger(msg="Two") def fun_two(a, b): print(a + b) sleep(1) fun_one(1, 2) fun_two(3, 4) # 结果如下: # 3 # func_One run time 1.0086338520050049 # 7 # func_Two run time 1.0099050998687744
作者:一个老宅男
微信:ZhengYing8887
出处:https://www.cnblogs.com/ZhengYing0813/
备注:本文版权归作者所有,欢迎转载和添加作者微信探讨技术,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
2019-10-31 python(random 模块)