装饰器笔记
装饰器原理理解
def html_tags(tag_name):
def wrapper_(func):
# @wraps(func)
def wrapper(*args, **kwargs):
content = func(*args, **kwargs)
return "<{tag}>{content}</{tag}>".format(tag=tag_name, content=content)
return wrapper
return wrapper_
#html_tags('b')(hello)(name='Andy')
#装饰器的拆开执行原理
#@html_tags('b') # hello = html_tags('b')(hello)
def hello(name='Toby'):
return 'Hello {}!'.format(name)
#print(hello())
# 不用@的写法如下
print(html_tags('b')(hello)())
# html_tag('b') 是一个闭包,它接受一个函数(hello),并返回一个函数
# hello = html_tags('b')(hello)
# hello = wrapper_(hello)
# hello = wrapper # 所以hell函数的名字hell.__name__ 为wrapper # 解决函数名称被覆盖需要用到functools 的 wraps
# hello() = wrapper()
# hello(name='Toby') = wrapper(name='Toby')
函数装饰器
函数装饰函数
from functools import wraps
def eat(fruit):
def wrapper_func(func_name):
@wraps(func_name)
def wrapper_inner(*args, **kwargs):
print("start decorator")
return func_name(*args, **kwargs)
print("eat:{}".format(fruit))
return wrapper_inner
return wrapper_func
@eat("banana")
def test_a(name):
print("name:{}".format(name))
if __name__ == "__main__":
test_a("tony")
# eat(fruit="apple")(test_a)(name="andy")
print(test_a.__name__)
函数装饰类
def decorator(cls):
def wrapper(*args, **kwargs):
print("decorator")
return cls(*args, **kwargs)
return wrapper
@decorator # Test=decorator(Test)
class Test():
def __init__(self, name):
self.name = name
def first_name(self):
print("test:{}".format(self.name))
t = Test('xiaoming')
print(t.__class__)
t.first_name()
类装饰器
类装饰器实现__call__方法,使类可以被调用
类装饰函数
class Decorator():
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("decorator_call")
return self.func(*args, **kwargs)
@Decorator # test = Decorator(test)
def test(a):
print("test{}".format(a))
test("sss")
# -----------------------------------------------------------
class Decorator():
def __init__(self, *args, **kwargs):
print("Decorator init")
pass
def __call__(self, func):
def wrapper(*args, **kwargs):
print("wrapper")
return func(*args, **kwargs)
return wrapper
class Decorator1(Decorator):
def __init__(self, *args, **kwargs):
print("Decorator1start")
super().__init__(*args, **kwargs)
print("Decorator1")
# @Decorator() # test = Decorator()(test)
@Decorator1() # test = Decorator1()(test)
def test(a):
print("test{}".format(a))
test("sss")
类装饰类
class Decorator():
def __init__(self, *args, **kwargs):
print("Decorator init")
pass
def __call__(self, cls):
def wrapper(*args, **kwargs):
print("wrapper")
return cls(*args, **kwargs)
return wrapper
@Decorator() # Test = Decorator()(Test)
class Test():
def __init__(self):
print("Test_init")
def a(self):
print("Test.a")
Test()
Test().a()
多装饰器执行顺序
靠近原函数的先装饰后执行,离原函数远的后装饰先执行
装饰器及多装饰器执行顺序