一、核心思想
在不改变被装饰对象内部代码和原有调用方式的基础之上在添加额外的功能
二、装饰器的实现过程
根据实际需要,一步一步满足需求,完成对装饰器的理解
1、简易版本
给index函数添加统计执行时间的功能
import time def index(): time.sleep(3) print('from index') def home(): time.sleep(2) print('from home') def func(): time.sleep(2) print('from home') def outer(func): # 外层函数 def get_time(): # 内层函数 # 1. 在函数执行之前打一个时间点 start_time = time.time() func() # index() # 2. 在函数执行完毕之后在打一个时间点 end_time = time.time() # 3. 两个时间的差值就是函数的实际执行时间 print("函数执行了:%s秒" % (end_time - start_time)) return get_time # 返回内层函数 # 利用闭包的形式来传参 # res = outer(index) # res:get_time的内存地址 # res() # get_time() home = outer(home) home()
2、解决参数的问题
当执行不同的函数,计算不同函数的执行时间,有的函数有参数,有的函数没参数
def index(name, username): time.sleep(3) print('from index') def home(name): time.sleep(2) print('from home', name) def outer(func): def get_time(*args, **kwargs): # 1. 在函数执行之前打一个时间点 start_time = time.time() func(*args, **kwargs) # 原有函数 # 2. 在函数执行完毕之后在打一个时间点 end_time = time.time() # 3. 两个时间的差值就是函数的实际执行时间 print("函数执行了:%s秒" % (end_time - start_time)) return get_time index = outer(index) index('tony', username='tank')
3、解决返回值问题
def home(name): time.sleep(2) print('from home', name) def index(): time.sleep(3) print('from index') return 'from index' def outer(func): # func = index def get_time(*args, **kwargs): # func:index # 1. 在函数执行之前打一个时间点 start_time = time.time() res=func(*args, **kwargs) # index() func('tony') # 2. 在函数执行完毕之后在打一个时间点 end_time = time.time() # 3. 两个时间的差值就是函数的实际执行时间 print("函数执行了:%s秒" % (end_time - start_time)) return res return get_time index = outer(index) res=index() print(res)
4、装饰器模板
def outer(func): def inner(*args, **kwargs): print('这个是函数执行之前可以添加的功能') res = func(*args, **kwargs) print('这个是函数执行之后可以添加的功能') return res return inner def index(): print('from index') index = outer(index) index()
5、装饰器的模板
def outer(func): def inner(*args, **kwargs): print('这个是函数执行之前可以添加的功能') res = func(*args, **kwargs) print('这个是函数执行之后可以添加的功能') return res return inner def index(): print('from index') index = outer(index) index()
6、装饰器的语法糖
''' 只要有一个函数认证成功,其他函数就不用验证了 需要一个变量来保存登录用户登录成功的标志 ''' is_login = {'is_login': False} # 使用闭包函数实现装饰器 def login(func): def auth(*args, **kwargs): # 可变长参数:接受多余的位置参数和关键字参数,没有参数则接受为空,不报错,正常执行,满足有参和无参两种使用场景 if is_login.get('is_login'): # 字典 get 方法取值为 False,表示 if False:条件不成立时不执行 # 前一个函数执行完,is_login赋值为 True,执行下面的代码 res = func(*args, **kwargs) # 调用函数,函数的返回值赋值给 res,再返回 res 给到 auth 函数 return res # 简易登录认证系统 username = input("Enter username: ").strip() passwd = input("Enter password: ").strip() # 验证用户名密码 if username == 'jingzhiz' and passwd == '123': print('登录成功!') # 函数执行前的操作 res = func(*args, **kwargs) # 要执行的函数 is_login['is_login'] = True return res # 函数执行后的操作 else: print('认证失败!') return auth ''' 语法糖需要定义在装饰器的下方,函数的上方紧贴着 去掉语法糖可以实现原函数的正常调用 语法糖格式@+装饰器外层函数名 @login的理解 index=login(),index 只是一个变量名,也可以是res,只是为了满足装饰器思想:不改变原函数的调用方式写成原函数名,打印内存地址于原函数不是一个 login()会返回 auth 的(函数名)即内存地址,实现 index = auth 即 index()=auth()。 ''' @login def index(name): print('from index', name) return '返回值测试' @login def home(): print('from home') # 装饰器的最终效果:保持函数的原始调用方式的同时,增加新的功能 res = index('jinghiz') print(res) home()
7、
标签:index,函数,python,res,time,print,装饰,def From: https://www.cnblogs.com/dgp-zjz/p/17443497.html