Python之装饰器-无参装饰器
装饰器介绍
1. 为何要用装饰器
- Python 中的装饰器是一种语法糖,可以在运行时,动态的给函数或类添加功能。
- 装饰器本质上是一个函数,使用 @ + 函数名就是可实现绑定给函数的第二个功能 。
- 将一些通用的、特定函数的功能抽象成一个装饰器,可以重复利用这些功能
2. 什么是装饰器
- “装饰”代指为被装饰对象添加新的功能,“器”代指器具/工具
- 装饰器的作用:就是在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能。
- 装饰器使用场景:插入日志、性能测试、事务处理、缓存、权限校验
- 可以调用的有:函数、方法、类
- 函数装饰器分为:无参装饰器和有参装饰,二者都是使用都是需要【名称空间+函数嵌套+闭包+函数对象的组合知识】
- 使用“@”符号定义装饰器,前提是需要有一个函数作为工具然后被“@”装饰到其他函数头上,为这个函数添加功能
无参装饰器
- @符号后是一个函数
- 虽然是无参装饰器,但是@后的函数本质上是单参函数
def add(x, y):print(add.__name__, x, y)return x + yadd(4, 5)
import time
print('------')
time.sleep(10)
print('******')
import datetime start = datetime.datetime.now()
end = datetime.datetime.now()
start, end
(end - start).total_seconds()
def add(x, y):return x + ydef logger(fn):ret = fn(4, 5)return retlogger(add)
def add(x, y):return x + ydef logger(fn, x, y):ret = fn(x, y)return retlogger(add, 4, 5)
def add(x, y):return x + ydef logger(fn, x, y):print(fn.__name__, x, y) ret = fn(x, y)return retlogger(add, 4, 5)
def add(x, y):return x + ydef sub(x, y): return x - ydef logger(fn, x, y):print(fn.__name__, x, y) ret = fn(x, y)return retlogger(add, 4, 5)
logger(sub, 5, 6)
def add(x, y):return x + ydef sub(x, y, z): return x - y - zdef logger(fn, *args, **kwargs): print(fn.__name__, args, kwargs) print('执行前可以做的事情,增强')ret = fn(*args, **kwargs)print('执行后可以做的事情,增强')return retlogger(add, 4, y=8)
logger(sub, 5, 6, z=7)
def add(x, y):return x + ydef sub(x, y, z): return x - y - zdef logger(fn):def inner(*args, **kwargs):print(fn.__name__, args, kwargs) print('执行前可以做的事情,增强')ret = fn(*args, **kwargs)print('执行后可以做的事情,增强')return retreturn innerlogger(add)(4, y=8)
def add(x, y):return x + ydef sub(x, y, z): return x - y - zdef logger(fn):def inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs)print('执行后可以做的事情,增强')return retreturn innerlogger(add)(4, y=8)
def add(x, y):return x + ydef sub(x, y, z): return x - y - zdef logger(fn): def inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs) print('执行后可以做的事情,增强')return retreturn innert = logger(add)
print(t(4, y=8))
def add(x, y):return x + ydef logger(fn): def inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs) print('执行后可以做的事情,增强')return retreturn inner
add = logger(add)
print(add(4, 5))

def add(x, y):return x + ydef logger(fn): def inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs) print('执行后可以做的事情,增强')return retreturn inner
print(hex(id(add)))
add = logger(add)
print(add(4, 5))
print(add.__closure__)
def logger(fn): def inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs) print('执行后可以做的事情,增强')return retreturn inner@logger
def add(x, y):return x + y
print(add(4, 5))
def logger(fn): def inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs) print('执行后可以做的事情,增强')return retreturn inner@logger
def add(x, y):return x + yprint(add(4, 5))
print(add.__name__)
def logger(wrapped): def wrapper(*args, **kwargs):print('执行前可以做的事情,增强', wrapped.__name__, args, kwargs)ret = wrapped(*args, **kwargs) print('执行后可以做的事情,增强')return retreturn wrapper@logger
def add(x, y):return x + yprint(add(4, 5))
print(add.__name__)
def logger(wrapped): def wrapper(*args, **kwargs):start = datetime.datetime.now()ret = wrapped(*args, **kwargs) delta = (datetime.datetime.now() - start).total_seconds()print("{} tooks {}s.".format(wrapped.__name__, delta))return retreturn wrapper@logger
def add(x, y):time.sleep(2)return x + yprint(add(4, 5))
print(add.__name__)