Python-闭包与装饰器
目录
闭包函数闭包函数本身是一个函数,是把闭包函数内部的函数 + 函数内部的变量包裹起来,然后通过返回值 返回出去。 闭包函数必须得符合函数嵌套 # 闭包函数:本身是一个函数,让其调用更方便 # 定义 # 把一个函数名 + 变量 封装成一个函数 返回(return)出去 def out_fun(url): # url = "qinyj" def iner_fun(): print(url) return iner_fun a = out_fun("url") a() 现在有一个函数,老板有一个需求,想在这个函数上加一个计时功能,就是计算这个函数执行时间,需求吩咐下去,某某公司的3个运维开发开始思考了。。。 def index(): print(from index) 第一个人 小青开始做。。。他的方式是修改源代码: import time def index(): start = time.time() print("from index") time.sleep(1) end = time.time() print(end - start) index() from index 1.0080575942993164 第二个人 小杰开始做。。。他的方式是在调用的时候计算时间 import time def index(): print("from index") time.sleep(1) start = time.time() index() end = time.time() print(end - start) from index 1.0000572204589844 第三个人 小强开始做。。。他用了一个非常牛逼的看不懂的骚操作。。 import time def index(): print("from index") def time_count(func): def inner(): start = time.time() func() time.sleep(1) end = time.time() print(end - start) return inner index = time_count(index) index() from index 1.0000572204589844 好了,现在三个人已经全部做完,老板该验收了,把他们三个人叫到会议室。。。 指明了小强做的非常不错!另外两个向他学习,小强做的方式就是装饰器 什么叫装饰器?装饰器:本身是一个函数,给已有的函数加功能 原则:不改变源代码 不改变其调用方式 刚才只有小强的代码符合上面规定
实现装饰器# v1 实现最简单的装饰器 import time def index(): """被装饰的函数""" print('index') time.sleep(1) # time_count装饰器:对被装饰函数计时 def time_count(func): # func才是真正的index """装饰器""" def wrapper(): start = time.time() func() end = time.time() print(end - start) return wrapper index = time_count(index) # index == wrapper index() # wrapper() # v2:带返回值 import time def index(): """被装饰的函数""" print('x',x) print('index') time.sleep(1) return 'index' # time_count装饰器:对被装饰函数计时 def time_count(func): # func才是真正的index """装饰器""" def wrapper(): start = time.time() res = func() # index() end = time.time() print(end - start) return res return wrapper index = time_count(index) # index == wrapper res = index() # wrapper() print(res) # v3:加参数 import time def index(x,y,z=10): """被装饰的函数""" print('x',x) print('index') time.sleep(1) return 'index' # time_count装饰器:对被装饰函数计时 def time_count(func): # func才是真正的index """装饰器""" def wrapper(*args,**kwargs): # (10,20) # *args和**kwargs接收了所有的参数 start = time.time() res = func(*args,**kwargs) # index() # *(10,20) # *args和**kwargs打散参数传给真正的index end = time.time() print(end - start) return res return wrapper index = time_count(index) # index == wrapper res = index(10,20,320) # wrapper() print(res) 以上均为二层装饰器:
如果实在理解不了,就记住装饰器模板: def deco(func): def wrapper(*args,**kwargs): # 要加什么功能就加上去 res = func(*args,**kwargs) return res return wrapper 装饰器语法糖在被装饰的函数上 加上 @装饰器函数名,目的是为了让代码更加简洁。 @time_count def index(x,x) print('index') time.sleep(1) return 'index' 三层装饰器三层装饰器就是给装饰器加参数,在原有的两层装饰器上再嵌套一层函数,利用闭包的思想,把函数变量和函数名返回出去。 username_list = [] def sanceng(role): def login_deco(func): def wrapper(*args,**kwargs): if username_list: print('已经登录,请勿重复登录') res = func(*args,**kwargs) return res username_inp = input('请输入用户名:') pwd_inp = input('请输入密码:') with open(f'{role}_info.txt','r',encoding='utf8') as fr: for user_info in fr: username,pwd = user_info.strip().split(':') if username_inp == username and pwd_inp == pwd: print('登录成功') username_list.append(username) res = func(*args,**kwargs) return res else: print('登录失败') return wrapper return login_deco @sanceng('admin') def index(x,y): print('index') print('x,y',x,y) return 123 res = index(10,20) print(res) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |