装饰器
装饰器
装饰器简介
"""
装饰器并不是一个新的知识
而是由我们之前所学习的 名称空间 函数对象 闭包函数组合而来
"""
器:指的是工具
装饰:给被装饰对象添加额外的功能
装饰器的原则
开放封闭原则
开发:对扩展开放
封闭:对修改封闭
装饰器核心思想
在不改变被"装饰对象内部代码"和"原有调用方式"的基础之上添加额外功能
拓展
import time time.sleep() # 让程序原地阻塞(睡)指定的秒数 time.time() # 时间戳(主要用于时间计算) """装饰器不是新的知识点 而是函数相关知识的整合"""
def index(): print('from index') index() # 统计index函数的执行时间 import time print(time.time()) # 1637036293.0609405 # 获取的结果叫时间戳(运行代码的那一刻距离1970-1-1所经历的秒数) time.sleep(3) # 让程序原地等待3秒 print('睡饱了') def index(): time.sleep(3) print('from index') # 统计index函数的执行时间 # 在函数运行之前统计一次时间 start_time = time.time() index() # 在函数运行完毕之后再次统计 end_time = time.time() # 计算差值 print(end_time - start_time)
# 给函数添加统计执行时间的功能 def outer(func): # func指向的是函数名index # func = index def get_time(): start_time = time.time() func() end_time = time.time() print('函数运行时间:%s' % (end_time - start_time)) return get_time # 将get_time函数名返回出去 index = outer(index) # outer(index函数名) # 左侧的变量名index指代是函数名get_time index()
import time def index(): time.sleep(3) print('亚洲最大的线上赌场开业了 双眼发红光的在线发牌!!!') def login(name): time.sleep(1) print('%s正在发牌'%name) def outer(func): # func指向的是函数名login # func = login def get_time(*args,**kwargs): start_time = time.time() func(*args,**kwargs) end_time = time.time() print('函数运行时间:%s' % (end_time - start_time)) return get_time # 将get_time函数名返回出去 login = outer(login) login('jason') index = outer(index) index()
import time def index(): time.sleep(3) print('亚洲最大的线上赌场开业了 双眼发红光的在线发牌!!!') return 'from index' def login(name): time.sleep(1) print('%s正在发牌'%name) return 'from login' def outer(func): # func指向的是函数名login # func = login def get_time(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) # 接收被装饰函数的返回值 end_time = time.time() print('函数运行时间:%s' % (end_time - start_time)) return res # 执行完get_time之后返回被装饰函数执行之后的返回值 return get_time # 将get_time函数名返回出去 # index = outer(index) # res = index() # print(res) login = outer(login) res1 = login('jason') print(res1)
from functools import wraps def outer(func): @wraps(func) # 修复技术就是为了让被装饰对象更加不容易被察觉装饰了 def inner(*args, **kwargs): print('执行函数之前可以添加的额外功能') res = func(*args, **kwargs) # 执行被装饰的函数 print('执行函数之后可以添加的额外功能') return res # 将被装饰函数执行之后的返回值返回 return inner
# 今天只需要掌握简单版本(每个都校验用户名和密码) # 记录用户状态的版本多花时间去练 import time def index(): time.sleep(1) print('百万大奖等你来拿 赶快加入我们吧!!!') def home(): time.sleep(1) print('学学学 一天到晚就是学 卷死你们这些家伙') def register(): time.sleep(1) print('注册功能') # 给index函数添加认证功能 """ 在调用index之前需要用户输入用户名和密码 正确才可以调用 错误直接拒绝 """ # 定义一个用于记录用户是否登录的数据 is_login = {'is_login':False} def login_auth(func): def auth(*args,**kwargs): # 1.1 先判断用户是否已经登录 if is_login.get('is_login'): # 3.正常执行函数index res = func(*args, **kwargs) return res # 1.先获取用户的用户名和密码 username = input('username>>>:').strip() password = input('password>>>:').strip() # 2.校验用户名和密码是否正确 if username == 'jason' and password == '123': # 3.正常执行函数index res = func(*args,**kwargs) # 4.将记录用户登录状态的数据修改 is_login['is_login'] = True return res else: print('用户名或密码错误 无法执行函数') return auth index = login_auth(index) index() home = login_auth(home) home() register = login_auth(register) register()
装饰器语法糖书写规范
语法糖必须紧贴在被装饰对象的上方
装饰器语法糖内部原理
会自动将下面紧贴着的被装饰对象名字当做参数传给装饰器函数调用
def outer(func): def inner(*args, **kwargs): print('执行函数之前可以添加的额外功能') res = func(*args, **kwargs) # 执行被装饰的函数 print('执行函数之后可以添加的额外功能') return res # 将被装饰函数执行之后的返回值返回 return inner @outer # index = outer(index) def index(*args, **kwargs): print('from index') @outer # home = outer(home) def home(): print('from home')
# 统计函数运行时间 import time def get_time(func): def inner(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) # 执行被装饰的函数 end_time = time.time() print('函数执行时间:%s'%(end_time-start_time)) return res # 将被装饰函数执行之后的返回值返回 return inner # 校验用户登录装饰 def login_auth(func): def inner(*args, **kwargs): # 1.先获取用户的用户名和密码 username = input('username>>>:').strip() password = input('password>>>:').strip() # 2.校验用户名和密码是否正确 if username == 'jason' and password == '123': res = func(*args, **kwargs) # 执行被装饰的函数 return res # 将被装饰函数执行之后的返回值返回 print('用户名或密码错误 无权限执行') return inner @login_auth @get_time def index(): time.sleep(1) print('from index') index()
from functools import wraps def outer(func): @wraps(func) # 修复技术就是为了让被装饰对象更加不容易被察觉装饰了 def inner(*args, **kwargs): print('执行函数之前可以添加的额外功能') res = func(*args, **kwargs) # 执行被装饰的函数 print('执行函数之后可以添加的额外功能') return res # 将被装饰函数执行之后的返回值返回 return inner @outer # index = outer(index) def index(): print('from index') print(index) help(index) def home(): """这是一个home函数""" print('from home') # help(index) # help(home) # print(index) # help(len)
def outer(source_data): # source_data = 'file' def login_auth(func): def auth(*args,**kwargs): # 2.校验用户名和密码是否正确 # 数据的校验方式可以切换多种 if source_data == 'file': # 从文件中获取用户数据并比对 print('file文件获取') elif source_data == 'MySQL': # 从MySQL数据库中获取数据比对 print('MySQL数据库获取') elif source_data == 'postgreSQL': # 从postgreSQL数据库中获取数据对比 print('postgreSQL数据库获取') else: print('用户名或密码错误 无法执行函数') return auth return login_auth @outer('file') def index(): print('from index') @outer('MySQL') def home(): print('from home') index() home()
# 判断七句print执行顺序 def outter1(func1): print('加载了outter1') def wrapper1(*args, **kwargs): print('执行了wrapper1') res1 = func1(*args, **kwargs) return res1 return wrapper1 def outter2(func2): print('加载了outter2') def wrapper2(*args, **kwargs): print('执行了wrapper2') res2 = func2(*args, **kwargs) return res2 return wrapper2 def outter3(func3): print('加载了outter3') def wrapper3(*args, **kwargs): print('执行了wrapper3') res3 = func3(*args, **kwargs) return res3 return wrapper3 @outter1 @outter2 @outter3 def index(): print('from index')
END