内容概要
装饰器的概念(重点)
装饰器简易版本
装饰器进阶版本
装饰器练习(认证功能)
装饰器固定模板
装饰器语法糖(简化代码)
有参装饰器
装饰器练习题(三层装饰器)
今日内容详细
装饰器的概念(重点)
"""
装饰器并不是一个新的知识
而是我们之前所学的 名称空间 函数对象 闭包函数组合而来
"""
器:指的是工具
装饰:给被装饰对象添加额外的功能
装饰器的原则
开放封闭原则
开放:对扩展开放
封闭:对修改封闭
装饰器核心思想
在不改变被"装饰对象内部代码"和"原有调用方式"的基础之上添加额外功能
def index():
print('from index')
index() # from index
# 统计index函数的执行时间
import time
# print(time.time())
# # 获取的结果叫时间戳(运行代码的那一刻距离1970-1-1所经历的秒数)
# time.sleep(2) # 让程序原地等待2秒
# print('睡饱了')
装饰器简易版本
# 给函数添加统计时间的功能
# def index():
# print('from index')
# time.sleep(1)
#
# import time
# def outer(func):
# def get_time():
# start_time = time.time()
# func()
# end_time = time.time()
# print('程序运行时间为:%s'%(end_time-start_time))
# return get_time
# index = outer(index)
# index() # 程序运行时间为:1.012636423110962
解决参数问题
# import time
# def index():
# time.sleep(1)
# print('开业了')
# def login(name):
# time.sleep(2)
# print('%s正在发牌'%name)
# def outer(func):
# 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
# index = outer(index)
# index() # 程序运行时间为:1.0100035667419434
# login = outer(login)
# login('tom') # 程序运行时间为:2.0142407417297363
解决返回值问题
# import time
# def index():
# time.sleep(1)
# print('开业了')
# return 'from index'
# def login(name):
# time.sleep(2)
# print('%s正在发牌'%name)
# return 'from login'
# def outer(func):
# 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
# return get_time
# index = outer(index)
# res = index() # 程序运行时间为:1.0100035667419434
# print(res) # from index
# login = outer(login)
# res = login('tom')
# print(res) # from login
认证装饰器
# 普通版本
# import time
# def index():
# time.sleep(1)
# print('开局一把刀 装备全靠爆')
# def home():
# time.sleep()
# print('往死里学')
# # 获取用户输入
# def login_auth(func):
# def auth(*args,**kwargs):
# username = input('username>>>:').strip()
# pwd = input('pwd>>>:').strip()
# if username == 'jason' and pwd == '123':
# print('用户%s登录成功' % username)
# res = func()
# return res
# else:
# print('用户名或密码输入错误')
# return auth
# index = login_auth(index)
# index()
# 进阶版本
import time
def index():
time.sleep(1)
print('开局一把刀 装备全靠爆')
def home():
time.sleep(1)
print('往死里学')
# 定义一个用户是否登录
is_login = {'is_login': False}
# 判断用户是否登录
def login_auth(func):
def auth(*args,**kwargs):
if is_login.get('is_login'):
res = func(*args, **kwargs)
return res
# 获取用户输入
username = input('username>>>:').strip()
password = input('ppasswore>>>:').strip()
if username == 'jason' and password == '123':
res = func(*args,**kwargs)
is_login['is_login'] = True
return res
else:
print('用户名或密码输入错误')
return auth
index = login_auth(index)
index()
home = login_auth(home)
home()
装饰器固定模板
# def outer(func):
# def inner(*args,**kwargs):
# print('执行函数之前可以添加的额外功能')
# res = func(*args,**kwargs) # 执行被装饰的函数
# print('执行函数之后可以添加的额外功能')
# return res
# return inner
装饰器语法糖
def outer(func):
def inner(*args,**kwargs):
print('执行函数之前可以添加的额外功能')
res = func(*args,**kwargs)
print('执行函数之后可以添加的额外功能')
return res
return inner
@outer
def index():
print('from index')
@outer
def home():
print('from home')
index()
home()
"""
装饰器语法糖书写规范
语法糖必须紧贴在被装饰对象的上方
装饰器语法糖内部原理
会自动将下面紧贴的被装饰对象名字当做参数传给装饰器函数调用
"""
双层语法糖
# import time
# def get_time(func):
# def inner(*args,**kwargs):
# start_time = time.time()
# res = func()
# end_time = time.time()
# print('程序运行时间为:%s'%(end_time-start_time))
# return res
# return inner
# def login_auth(func):
# def auth(*args,**kwargs):
# username = input('username>>>:').strip()
# password = input('password>>>:').strip()
# if username == 'jason' and password == '123':
# res = func(*args, **kwargs)
# return res
# print('用户名或密码输入错误')
# return auth
#
# @login_auth
# @get_time
# def index():
# time.sleep(1)
# print('开局一把刀 装备全靠爆')
# index()
# @login_auth
# @get_time
# def home():
# time.sleep(1)
# print('往死里学')
# home()
装饰器修复技术
from functools import wraps
def outer(func):
@wraps(func)
def inner(*args,**kwargs):
print('执行函数之前可以添加的额外功能')
res = func(*args,**kwargs)
return res
return inner
@outer
def index():
print('from index')
print(index)
help(index)
#
def home():
"""这是一个home函数"""
print('from index')
print(home) # 打印函数home的内存地址
help(home) # 打印函数home解释
help(len) # 打印函数len解释