装饰器笔记

装饰器原理理解

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()

多装饰器执行顺序

靠近原函数的先装饰后执行,离原函数远的后装饰先执行
装饰器及多装饰器执行顺序

posted @ 2020-05-06 09:57  左岸丶  阅读(91)  评论(0)    收藏  举报