装饰器:
定义一个系统的版本,在做版本升级时 会用到装饰器
努力做到既不修改源代码 还可以增加新功能
修改代码的一个原则就是开放封闭原则
不能修改被装饰对象(函数)的源代码
不能修改修饰对象的调用方式,且能够达到增加功能的效果
给'花瓶'装饰一下
def vase():
print('插花')
vase()
增加一个观赏功能
def vase():
print('插花')
print('观赏')
wrap(vase)
开放不封闭
def fn():
vase()
print('观赏')
vase = fn():
vase()
开放且封闭 但是程序是个死循环
def vase():
print('插花')
tag=vase
def fn():
tag()
print('观赏')
vase = fn
vase()
这就是装饰器的雏形,我们对其进一步优化
def vase()
print('插花')
def wrap(tag):
def inner():
tag()
print('观赏')
return inner
vase=warp(vase)
vase()
语法糖
def wrap(fn)
def inner():
fn()
print('观赏')
return inner
@wrap
def vase()
print('插花')
vase()
一个函数可以被任意一个相关装饰器装饰,也可以被任意几个装饰器装饰
装饰的顺序会影响新增功德执行顺序
装饰器和可变长参数的结合
def wrap(fn):
def inner(*args, **kwargs):
print(args)
print(kwargs)
result = fn(*args, **kwargs)
print('新增功能')
return result
return inner
@wrap
def func(a, b, c, *, x, y, z):
print(a, b, c, x, y, z)
print('原有功能')
func(1, 2, 3, x=10, y=20, z=30)
有参装饰器的一个案例 在装饰器内带参数
def auth(driver='file'):
def auth2(func):
def wrapper(*args,**kwargs):
name = input('usr:')
pwd = input('password:')
if driver == 'file':
if name=='egon'and pwd == '123':
print('login success')
res = func(*args,**kwargs)
return res
elif driver == 'ldap':
print('ldap')
return wrapper
return auth2
@auth(driver='ldap')
def foo(name):
print(name)
foo('egon')