装饰器推导
"""
装饰器(decorator):
理解这个知识点的精髓
思考:
1.问题:模拟完成用户的增删改功能
2.问题:在操作用户时添加日志功能,日志代码过多,会造成代码冗余
解决: 抽取日志函数,在功能性函数中调用即可
3.问题:log()代码需要修改的功能性代码过多,个人工作量大
解决: 以功能性函数作为参数,在日志内部执行功能性函数,对其增强
4.问题:调用功能性代码发生变化,调用者也会发生变化,考虑能不能不改变原有代码对其增加日志考虑
解决:使用返回值为函数,对函数进行增强,给当前log函数一个函数参数,返回一个
新的增强之后的函数,并将返回后的函数命名为原功能性函数
1.什么是装饰器?
就是一个函数
作用:在不改变原有代码的情况下,对函数本身进行增强
2.装饰器语法糖 --sweet
@ + 装饰器函数名称
"""
推导过程
python
#装饰器:本质就是一个函数
def log(func):
def wrapper():
print("log.......before....")
func()
print("log.......after....")
return wrapper
@log
def add_user():
print("add user ......")
@log
def del_user():
print("del user ......")
@log
def upd_user():
print("upd user ......")
#add_user = log(add_user)
print("---增加---")
add_user()
print("---删除---")
del_user()
print("---更改---")
upd_user()
# del_user()
# upd_user()
函数装饰器
"""
函数装饰器
1.装饰器传递
建议在装饰器参数传递的过程中使用参数的通用
*args,**kwargs
2.无参装饰器
3.有参装饰器
有参装饰器与无参装饰器的区别
python
#1.无参装饰器
# def log(func):
# def wrapper(*args, **kwargs):
# print("log......")
# func(*args,**kwargs)
# return wrapper
#2.有参装饰器
def log(user,time):
def decorator(func):
def wrapper(*args, **kwargs):
print(f"log......{user}.....{time}")
func(*args,**kwargs)
return wrapper
return decorator
import time
user = "lisi"
time = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
@log(user,time)
def add_user(username,password):
print(f"add....{username}......{password}")
add_user("zhangsan","123456")
无参装饰器练习
python
#让传入的值自加100
def add_number(func):
def wrapper(*args,**kwargs):
result = func(*args,**kwargs)
new_result = result + 100
return new_result #result + 100
return wrapper
@add_number
def print_number(number):
return int(number)
print(print_number(666))
类装饰器
"""
类装饰器 --魔术方法 __call__() 专门在类中定义装饰器
1.无参类装饰器
2.有参类装饰器
3.装饰器的顺序问题
离原函数越近的的装饰器,先增强
"""
有参装饰器与无参装饰器的区别
python
#1.无参类装饰器
class log():
#通过构造方法传递原函数对象
def __init__(self,func):
self.func = func
#通过call实现装饰器函数
def __call__(self,*args,**kwargs):
print("log......") #增强的代码
self.func(*args,**kwargs)
#2.有参类装饰器
class args_log():
#通过构造方法传递装饰器的参数
def __init__(self,user,time):
self.user = user
self.time = time
#通过call方法传递原函数对象
def __call__(self,func):
def wrapper(*args,**kwargs):
print(f"log......{self.user}...{self.time}")
func(*args,**kwargs)
return wrapper
import time
user = "lisi"
time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
@log
@args_log(user,time)
def add_user(username,password):
print(f"add user......{username}......{password}")
add_user("admin","<PASSWORD>")
装饰器案例练习
题目
"""
1.请实现一个装饰器,通过一次调用使函数重复执行五次
2.请实现一个装饰器,每次调用函数时,将函数名字以及调用此函数的时间点写入文件中
3.完成文件写入功能,任意写入一个字符,编写装饰器,实现写入文件时增加当前系统时间
"""
第一题
python
#1.函数的无参装饰器
# def loop_5(func):
# def wrapper(*args, **kwargs):
# for i in range(5):
# func(*args, **kwargs)
# return wrapper
#2.类的无参类装饰器 __init__ 函数本身 call:装饰器功能
class loop_5():
#func = 0x1233
def __init__(self,func):
self.func = func
def __call__(self,*args,**kwargs):
for i in range(5):
self.func(*args,**kwargs)
@loop_5
def test():
print("test......")
test()
第二题
python
#练习二;
#1.函数的有参装饰器
import time
time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
# def write_file(time):
# def decorator(func):
# def wrapper(*args,**kwargs):
# #写入函数名字和时间点
# with open("../test.txt","a+",encoding="utf-8") as f:
# f.write(f"func_name: {func.__name__},time: {time}\n")
# func(*args,**kwargs)
# return wrapper
# return decorator
#2.类的有参装饰器
class write_file():
def __init__(self,time):
self.time = time
def __call__(self,func):
def wrapper(*args,**kwargs):
#写入文件
with open("../test.txt","a+",encoding="utf-8") as f:
f.write(f"func_name: {func.__name__},time: {self.time}\n")
func(*args,**kwargs)
return wrapper
@write_file(time)
def test2():
print("test2.....")
test2()
第三题
python
#练习3
class write_file2():
def __init__(self,time):
self.time = time
def __call__(self,func):
def wrapper(*args,**kwargs):
with open("../test_log2.txt","a+",encoding="utf-8") as f:
f.write(f"time: {self.time}\n")
func(*args,**kwargs)
return wrapper
@write_file2(time)
def test3(str):
with open("../test_log2.txt","a+",encoding="utf-8") as f:
f.write(str)
test3("have a luck day\n")
