【一】装饰器介绍
【1】什么是装饰器
【2】装饰器的用途
【3】装饰器的分类
【4】装饰器的原理
【二】无参装饰器
【1】什么是无参装饰器
【2】推导装饰器的语法
(1)面条版
import time
start_time = time.time()
print(f"我开始睡觉了 .... ")
time.sleep(2)
print(f"我结束睡觉了 .... ")
end_time = time.time()
print(f"当前程序总耗时 :>>>> {end_time - start_time} s")
(2)函数版
import time
def show():
print(f"我开始睡觉了 .... ")
time.sleep(2)
print(f"我结束睡觉了 .... ")
def show_show():
print(f"我开始睡觉了 .... ")
time.sleep(1)
print(f"我结束睡觉了 .... ")
start_time = time.time()
show()
end_time = time.time()
print(f"当前程序总耗时 :>>>> {end_time - start_time} s")
(3)闭包函数
import time
def show():
print(f"我开始睡觉了 .... ")
time.sleep(2)
print(f"我结束睡觉了 .... ")
def show_show():
print(f"我开始睡觉了 .... ")
time.sleep(1)
print(f"我结束睡觉了 .... ")
def outer(func):
def inner():
func()
print(func)
return inner
【3】装饰器推导
(1)需求
(2)普通版-修改源代码
user_data_dict = {'username': "max", "password": "123"}
def withdral():
username = input("username :>>>> ")
password = input("password :>>>> ")
if username == user_data_dict.get('username') and password == user_data_dict.get('password'):
print(f"登录成功")
print(f"这是登陆成功后才能看到的动作片")
else:
print("登录失败")
def transform():
username = input("username :>>>> ")
password = input("password :>>>> ")
if username == user_data_dict.get('username') and password == user_data_dict.get('password'):
print(f"登录成功")
print(f"转账功能")
else:
print("登录失败")
withdral()
transform()
(2)闭包函数-增加校验逻辑
def outer(func):
def inner():
username = input("username :>>>> ")
password = input("password :>>>> ")
if username == user_data_dict.get('username') and password == user_data_dict.get('password'):
print(f"登录成功")
func()
else:
print("登录失败")
return inner
def transform():
print(f"这是在转账功能")
transform = outer(transform)
transform()
def withdral():
print(f"这是取款功能")
withdral = outer(withdral)
【4】无参装饰器模板
def outer(func):
'''
:param func: 每一次需要调用传递的函数
:return:返回值是内嵌函数 inner 的函数内存地址
'''
def inner():
func()
return inner
【三】有参装饰器
【1】无参装饰器
def outer(func):
def inner():
func()
return inner
def transform(username, money):
print(f"向 {username} 转账 {money}")
transform = outer(transform)
transform()
【2】有参装饰器
def outer(func):
def inner(username, money):
func(username, money)
return inner
def transform(username, money):
print(f"向 {username} 转账 {money}")
username = 'qwe'
money= 10000
transform = outer(transform)
transform(username,money)
【3】有参装饰器优化
def outer(func):
def inner(*args,**kwargs):
func(*args,**kwargs)
return inner
def transform(username, money):
print(f"向 {username} 转账 {money}")
username = 'qwe'
money= 10000
transform = outer(transform)
transform(username,money)
【4】有参装饰器模板
def outer_no(func):
def inner():
func()
return inner
def outer_yes(func):
def inner(*args, **kwargs):
func(*args, **kwargs)
return inner
【四】装饰器语法糖
【1】无参装饰器语法糖
(1)没有语法糖的时候
import time
def timer(func):
def inner():
start = time.time()
func()
end = time.time()
print(f"总耗时 :>>>> {end - start} s")
return inner
def transform():
time.sleep(1)
transform = timer(transform)
transform()
(2)有语法糖的时候
def timer(func):
def inner():
start = time.time()
func()
end = time.time()
print(f"总耗时 :>>>> {end - start} s")
return inner
@timer
def transform():
time.sleep(1)
transform()
【2】有参装饰器语法糖
def timer(func):
def inner(*args,**kwargs):
start = time.time()
func(*args,**kwargs)
end = time.time()
print(f"总耗时 :>>>> {end - start} s")
return inner
@timer
def transform(username,money):
print(f"{username} | {money}")
time.sleep(1)
transform("max",500)
【3】有参语法糖
(1)单语法糖
login_dict = {'username': 'max'}
def login_auth(func):
def inner(*args, **kwargs):
if login_dict.get('username'):
func(*args, **kwargs)
else:
print(f"请先登录!")
return inner
def timer(func):
def inner(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
end = time.time()
print(f"总耗时 :>>>> {end - start} s")
return inner
@login_auth
def transform(username, money):
print(f"{username} | {money}")
time.sleep(1)
transform("max", 500)
(2)多语法糖
login_dict = {'username': None}
def decrator(tag):
'''
:param tag: 'login_auth' ---> 登录认证装饰器
'timer' ---> 返回 计时装饰器
:return:
'''
if tag == "login_auth":
def login_auth(func):
def inner(*args, **kwargs):
if login_dict.get('username'):
func(*args, **kwargs)
else:
print(f"请先登录!")
return inner
return login_auth
elif tag == "timer":
def timer(func):
def inner(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
end = time.time()
print(f"总耗时 :>>>> {end - start} s")
return inner
return timer
def transform(username, money):
print(f"{username} | {money}")
time.sleep(1)
transform = decrator(tag="timer")(transform)
transform('chosen',999)
print(transform)
(3)多语法糖优化
login_dict = {'username': None}
def decrator(tag):
'''
:param tag: 'login_auth' ---> 登录认证装饰器
'timer' ---> 返回 计时装饰器
:return:
'''
if tag == "login_auth":
def login_auth(func):
def inner(*args, **kwargs):
if login_dict.get('username'):
func(*args, **kwargs)
else:
print(f"请先登录!")
return inner
return login_auth
elif tag == "timer":
def timer(func):
def inner(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
end = time.time()
print(f"总耗时 :>>>> {end - start} s")
return inner
return timer
else:
print(f"无参数的",tag)
@decrator(tag='timer')
def transform(username, money):
print(f"{username} | {money}")
time.sleep(1)
transform("chosen",999)
【4】多层语法糖案例
(1)不使用语法糖
def dec_a(func):
print('111')
def wrapper(*args, **kw):
print('222')
func(*args, **kw)
print('333')
return wrapper
def dec_b(func):
print('aaa')
def wrapper(*args, **kw):
print('bbb')
func(*args, **kw)
print('ccc')
return wrapper
@dec_a
@dec_b
def main_func():
print('main_func')
'''
# 定义顺序是一个个挨着定义
# 调用顺序是倒着谁在下先调用谁
main_func = dec_b(main_func)
# main_func = b_wrapper (main_func)
main_func = dec_a(main_func)
# main_func = a_wrapper (b_wrapper(main_func))
main_func()
# a_wrapper
# aaa
# 111
# 222
# bbb
# main_func
# ccc
# 333
'''
main_func()
(2)使用语法糖
def dec_a(func):
print('111')
def wrapper(*args, **kw):
print('222')
func(*args, **kw)
print('333')
return wrapper
def dec_b(func):
print('aaa')
def wrapper(*args, **kw):
print('bbb')
func(*args, **kw)
print('ccc')
return wrapper
@dec_a
@dec_b
def main_func():
print('main_func')
'''
# aaa
# 111
# 222
# bbb
# main_func
# ccc
# 333
'''
main_func()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!