Python装饰器
1) print打印语句耦合太高,输出信息的功能,属于非业务代码。灵活度太差。
print在业务代码中是属于侵入式代码。
2)装饰器
#第一步代码
def add(x,y):
return x+y
def logger(fn):
print('before')
ret=fn(4,5)
print('end')
return ret
print(logger(add))
#第二步多个参数优化
def add(x,y):
return x+y
def add1(x,y,*,z=6):
return x+y+z
def logger(fn,*args,**kwargs):
print('before')
ret=fn(*args,**kwargs)
print('end')
return ret
a=logger(add1,4,5,z=7)
print(a)
#第三步
def add(x,y):
return x+y
def add1(x,y,*,z=6):
return x+y+z
def logger(fn):
def _logger(*args,**kwargs):
print('before')
ret=fn(*args,**kwargs) #调用add1
print('end')
return ret
return _logger
add1=logger(add1) #内层函数_logger
a=add1(4,5,z=7) #logger(add1,4,5,z=7)
print(a)
#第四步
def add(x,y):
return x+y
def add1(x,y,*,z=6):
return x+y+z
def logger(fn):
def _logger(*args,**kwargs):
print('before')
ret=fn(*args,**kwargs) #调用add1
print('end')
return ret
return _logger
#add1=logger(add1) #内层函数_logger
a=logger(add1)(4,5,z=7) #logger(add1,4,5,z=7)
print(a)
#第五步
def add(x,y):
return x+y
def logger(fn):
def _logger(*args,**kwargs):
print('before')
ret=fn(*args,**kwargs) #调用add1
print('end')
return ret
return _logger
@logger
def add1(x,y,*,z=6): #add1 = logger(add1)
return x+y+z
#add1=logger(add1) #内层函数_logger
a=add1(4,5,z=7) #logger(add1,4,5,z=7)
print(a)
#第六步包装函数wrapper
def logger(fn):
def wrapper(*args,**kwargs):
print('before')
ret = fn(*args,**kwargs)
print('end')
return ret
return wrapper
@logger
def add(x,y,*,z=6):
return x+y+z
@logger
def add1(x,y): #add=logger(add)
return x+y
#b=logger(add)
a=add(4,5,z=10)
print(a)
3)@logger的语法格式。
装饰器(无参)
他是一个函数,函数作为他的形参。
返回的值也是一个函数。
可以使用@function调用。
Wrapper表示被包装函数。
Wrapperd表示包装函数。
4)装饰器和高阶函数。
装饰器是高阶函数,但是装饰器是对传入的函数的功能进行装饰,功能增强。
#装饰器
增强函数,而不是非侵入式函数。把函数名作为其参数。
装饰器:Python中的装饰器是一种语法糖,是一个函数,使用的函数作为参数传入。功能往往写成高阶或者嵌套函数,为了不侵入元函数。增强其功能。分为带参与无参的装饰器。
import datetime
import time
def logger(fn):
def wrapper(*args,**kwargs):
print("args={},kwargs={}".format(args,kwargs))
start = datetime.datetime.now()
ret = fn(*args,**kwargs)
duration = datetime.datetime.now() - start
print("function{}took{}s.".format(fn.__name__,duration.total_seconds()))
return ret
return wrapper
@logger #add = logger(add)
def add(x,y):
print("===call add =======")
time.sleep(2)
return x+y
print(add(4,y=1))
装饰器:装饰器函数,前置功能增强,被增强函数,后置功能增强。
#import datetime
import time
def logger(fn):
def wrapper(*args,**kwargs):
print("{}{}".format(args,kwargs))
start = datetime.datetime.now()
n = fn(*args,**kwargs)
duration=datetime.datetime.now() - start
print("function{}took{}s".format(fn.__name__,duration.total_seconds()))
return n
return wrapper
@logger
def add(x,y):
print("====call add =======")
time.sleep(2)
return x+y
b=add(3,y=4)
print(b)
装饰器的作用
1)装饰器是AOP面向切面编程的思想体现。
面向对象往往需要通过继承或者组合依赖等方式调用一些功能,这些功能的代码往往可能在多个类中出现。比如logger,这样造成代码的重复,增加了耦合,logger改变影响所有使用他的类或者方法。
而AOP在需要的类或方法上切下,前后的切入点可以加入增强的功能,比如logger函数功能就是对 业务函数增加日志,而业务函数中应该把业务函数无关的日志功能剥离干净。
2)装饰器的应用场景:
日志、监控、权限、设计、参数检查、路由等处理:
这些功能与业务功能无关,很多业务都需要公共功能,所以适合独立出来,需要的时候,对目标对象增强。
浙公网安备 33010602011771号