因为Odoo里有大量的装饰器,所以决定把这个理得清晰一些。
装饰模式
23种设计模式之一,英文叫Decorator Pattern,又叫装饰者模式。装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
特征什么的参考百度吧
python的装饰器
python装饰器跟类扯不上关系(或许我无知),跟装饰模式一样,他也是用包裹的,就像穿衣服一样。一般用来装饰function,不修改原function的任何内容和逻辑。调用时候还是这个function的名称,十分方便。
总想起网上那种为了不让你改名字,调用10w次,好极端。其实,通过修改原函数可以解决一切问题,只是你愿不愿意,大家都想穿漂亮的衣服不是。
他的优点基本如下:
1.减少函数嵌入
2.函数前置拦截
3.提高代码可读性
下面是个成熟的代码,say比较简单,do包含了传参,finish包裹了2层。装饰器主要是@blablabla。
def debug(func):
def wrapper(*args, **kwargs): # 指定宇宙无敌参数
print("[DEBUG]: enter {}()".format(func.__name__))
print('Prepare and say...')
func(*args, **kwargs)
return wrapper # 返回
@debug
def say(something):
print("hello {}!".format(something))
#这里有个调用
say(something='a')
def logging(level):
def wrapper(func):
def inner_wrapper(*args, **kwargs):
print("[{level}]: enter function {func}()".format(
level=level,
func=func.__name__))
return func(*args, **kwargs)
return inner_wrapper
return wrapper
@logging(level='INFO')
def say(something):
print("say {}!".format(something))
# 如果没有使用@语法,等同于
# say = logging(level='INFO')(say)
@logging(level='DEBUG')
def do(something):
print("do {}...".format(something))
@debug
@logging(level='LOG')
def finish(something):
print("finish {}".format(something))
if __name__ == '__main__':
print('=====================')
#注意和上面的say不同这里没有debug装饰器了
say('hello')
print('=====================')
do("my work")
print('=====================')
finish('job')
这是个加log和debug的例子,也是装饰器的常用案例。包含了传递参数和多个装饰器调用。对于多个装饰器,请注意finish例子中DEGUG那行的func name。
其实,通过修改原函数可以解决一切问题,这句当我没说。