python函数装饰器
目录
装饰器
一. 什么是装饰器
器:指的是工具
装饰:给被装饰对象添加额外的功能
二. 装饰器的原则
开放:对扩展开放
封闭:对修改封闭
三. 装饰器核心思想
在不改变被"装饰对象内部代码"和"原有调用方式"的基础之上添加额外功能
四. 装饰器简易版本
# 给函数添加统计执行时间的功能
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 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')
六. 解决返回值问题
import time
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函数名返回出去
login = outer(login)
res1 = login('jason')
print(res1)
七. 一次性登录认证( 练习)
import time
def index():
time.sleep(1)
print('百万大奖等你来拿 赶快来加入我们把!!!')
def home():
time.sleep(1)
print('学学学 一天到晚就是学 卷死你们这些家伙')
def register():
time.sleep(1)
print('注册功能.')
dic = {'state': False}
def outter(func):
def inter(*args, **kwargs):
while True:
if dic['state'] == False: # 验证之前是否已经成功登陆
username = input('请输入用户名>>>:').strip() # 增加功能
pwd = input('请输入密码>>>:').strip()
if username == 'jason' and pwd == '123':
dic['state'] = True # 登录成功则之后不需要再次验证登录
res = func(*args, **kwargs)
return res
else:
print('用户名或密码错误.')
# return res
else:
res = func(*args, **kwargs)
return res
return inter
# 这样就可以验证一次登录就直接依次运行后续操作
index = outter(index)
index()
home = outter(home)
home()
register = outter(register)
register()
八. 装饰器固定模板
def outer(func):
def inner(*args, **kwargs):
print('执行函数之前可以添加的额外功能')
res = func(*args, **kwargs) # 执行被装饰的函数
print('执行函数之后可以添加的额外功能')
return res # 将被装饰函数执行之后的返回值返回
return inner
# 调用的时候用
@outer
def xx():
# 这样函数xx就拥有了函数outer的装饰器功能了
九. 装饰器语法糖
-
装饰器语法糖书写规范
语法糖必须紧贴在被装饰对象的上方
-
装饰器语法糖内部原理
会自动将下面紧贴着的被装饰对象名字当做参数传给装饰器函数调用
十. 双层语法糖
十一. 装饰器修复技术
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)
# 调from functools import wraps模块 加 @wraps(func)是让打印改名后的index内存地址也是显示函数名index 而不调用的话显示实际调用的函数名inner
十二. 3层语法糖
十三.有参装饰器
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()