【一】什么是装饰器
-
装饰器指的就是为被装饰的对象添加新的功能
-
器 代表工具 增加后的调用方式不变
-
在不改变源代码和调用方式的基础上增加额外的新功能
【二】装饰器的用途
-
对上线后的程序进行新功能的增加和修改
-
给一个功能增加新的需求或者改变原来的程序运行逻辑
【三】装饰器的分类
【1】有参装饰器
【2】无参装饰器
-
即没有参数的装饰器
【四】装饰器的原理
-
闭包函数 + 函数对象的组合使用
【五】无参推导装饰器的语法
【1】为一段代码增加计时功能
(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") # 2s
(2) 函数
import time def outer():print(f"开始")time.sleep(2)print(f"结束") # 开始记录 start_time = time.time() outer() # 结束记录 end_time = time.time() # 总消耗时间 print(f"当前程序总耗时:{end_time - start_time} s")
(3)闭包函数
import time def show_show():print(f'开始')time.sleep(3)print(f'结束')def outer(func):def inner():func()# print(func) 这里的func 已经是show_show return inner inners = outer(show_show) inners()
【小练习】
定义一个用户数据字典 校验当前用户名和密码是否正确,如果正确则打印登录成功 否则打印失败
方法一:最原始最low
user_dict = {'username': 'knight', 'password': '123'} def show(): username_input = input(f"请输入用户名").strip()password_input = input(f"请输入密码").strip()if username_input == user_dict.get('username') and password_input == user_dict.get('password'):print(f"这是登陆成功后才能看到的动作片")else:print(f'登录失败') show()
方法二:使用装饰器
user_dict = {'username': 'knight', 'password': '123'} def outer(func):def inner():username_input = input(f"请输入用户名").strip()password_input = input(f"请输入密码").strip()if username_input == user_dict.get('username') and password_input == user_dict.get('password'):print(f"登录成功")func()else:print(f"登录失败") return inner def transform(): # 添加转账功能print(f'转账功能') tra = outer(transform) # tra = inner = outer(transform) tra() def withdral(): # 添加取款功能print(f'取款功能') dral = outer(withdral) # dral = inner = outer(withdral) dral()
无参装饰器的模板
def outer(func):''' :param func: 每一次需要调用传递的函数:return: 返回值是内嵌函数 inner 的函数内存地址''' def inner():# 在func()之前可以使用if等方法增加逻辑校验# 当符合指定条件后,可以允许执行传递进来的函数# 不符合条件的时候不执行函数func()# 在func()之后也可以做逻辑校验 return inner
【六】有参装饰器
【1】根据指定的位置参数传递参数
def outer(func):def inner(usernam, monery):func(username, money) return inner def transform(usrname, monery):print(f'向{username}转账{money}') username = 'hyt' money = 100000 transform(username, money) tra = outer(transform)
【2】用可变长位置参数和可变长关键字参数,接收函数所需的参数
def outer(func):def inner(*args, **kwargs):func(*args, **kwargs) return inner def transform(usrname, monery):print(f'向{username}转账{money}') username = 'hyt' money = 100000 transform(username, money) tra = outer(transform)