python装饰器
一、装饰器
装饰:装修,房子就是可以住的,如果装修,不影响你住,而且体验更加,让你生活中增加了很多功能:洗澡,看电视,沙发休息。
器:工具
开放封闭原则:
开放:对代码的拓展是开放的。
封闭:对源码的修改是封闭的。
装饰器:完全遵循开放封闭原则,装饰器就是一个函数。
在不改变原函数代码以及调用方式前提下,为其增加新的功能。本质是闭包
标准版。
def wrapper(f): # f 为被装饰函数
def inner(*args, **kwargs): # 给被装饰函数传参
'''添加额外的功能:被执行装饰函数之前的操作'''
ret = f(*args, **kwargs)
'''添加额外的功能:被执行装饰函数之后的操作'''
return ret # 返回被装饰函数的返回值
return inner
举例:给index函数新增一个功能测试函数执行效率:
import time
def timmer(f): # 装饰器要写在最前面。f 是被装饰函数。
# 当装饰dariy函数时,函数的定义:* 聚合 args = ('小杨',20)
def inner(*args, **kwargs): # 因为实际执行的是inner,用inner传参给被装饰函数
start_time = time.time()
# 函数的执行:* 打散:f(*args) --> f(*('小杨',20)) --> f('小杨',20)
r = f(*args, **kwargs) # 给被装饰函数传参,在此处被传进去的参数会被打散,并且被装饰函数的返回值赋给r,
end_time = time.time()
print(f'测试函数的执行效率:{end_time - start_time}')
return r # 返回被装饰函数的返回值
return inner
@timmer # 相当于 index = timmer(index)
def index(name):
'''
有很多代码.....
'''
time.sleep(0.5) # 模拟网络延迟或者代码效率。
print(f'欢迎{name}登录博客首页')
return 'index的返回值:666'
@timmer
def dariy(name,age):
'''
有很多代码.....
'''
time.sleep(0.5) # 模拟网络延迟或者代码效率。
print(f'欢迎{age}岁的{name}登录日记首页')
ret = index('小杨') # 相当于--》ret = inner('小杨')
print(ret) # 打印index的返回值,实际上是inner的返回值,在inner函数那里做了个转换
print('---------------')
dariy('小杨', 20) # 相当于--》inner('小杨', 20)
二、带参数的装饰器
标准版
def parameter(path): # 给wrapper装饰器传入参数
def wrapper(f): # f 为被装饰函数
def inner(*args, **kwargs): # 给被装饰函数传参
'''添加额外的功能:被执行装饰函数之前的操作'''
f'''给装饰器传入的参数是:{path}'''
ret = f(*args, **kwargs)
'''添加额外的功能:被执行装饰函数之后的操作'''
return ret # 返回被装饰函数的返回值
return inner
return wrapper
在函数到@wrapper时会变成——>被装饰函数 = inner(被装饰函数)
在当遇到带参数的装饰器时@parameter('abc')会变成——>先执行parameter('abc')函数,并返回值wrapper之后就是正常装饰器了@wrapper。
列如:将每个模块的调用日志写进相应的日志文件里面去
import time
def parameter(path): # 将日志文件名传入装饰器里
def wrapper(f):
def inner(*args, **kwargs):
with open(path, encoding='utf-8', mode='a') as f1:
f1.write(f'访问时间{time.strftime("%Y-%m-%d %H:%M:%S")},函数名{f.__name__}')
ret = f(*args, **kwargs)
return ret
return inner
return wrapper
@parameter('login.txt') # 相当于-->wrapper = parameter('login.txt')
def login():
print('欢迎登录:')
@parameter('register.txt')
def register():
print('欢迎注册:')
@parameter('goods.txt')
def goods():
print('欢迎购物:')
goods()
login()
register()
本文来自博客园,作者:Mr-Yang`,转载请注明原文链接:https://www.cnblogs.com/XiaoYang-sir/p/14675637.html