装饰器的各种实现方式

无参数装饰器

方式一:闭包

def decorator(func):
    def inner(*args, **kwargs):
        print('执行前')
        ret = func(*args, **kwargs)
        print('执行后')
        return ret
    return inner

方式二:类

class decorator(object):
    def __init__(self, func):
        self.func = func
    
    def __call__(self, *args, **kwargs):
        print('执行前')
        ret = self.func(*args, **kwargs)
        print('执行后')
        return ret

方式三:偏函数+lambda

from functools import partial

def decorator(func, *args, **kwargs):
    print('执行前')
    ret = func(*args, **kwargs)
    print('执行后')
    return ret


new_decorator = lambda func: partial(decorator, func)

方式四:偏函数

from functools import partial


def decorator(func, *args, is_inner=False, **kwargs):
    if not is_inner:
        return partial(decorator, func, is_inner=True)
    
    print('执行前')
    ret = func(*args, **kwargs)
    print('执行后')
    return ret

带参数的装饰器

方式一:闭包

def decorator(name):
    def wrap(func):
        def inner(*args, **kwargs):
            print('执行前')
            ret = func(*args, **kwargs)
            print('执行后')
            return ret
        return inner
    return warp

方式二:闭包

def decorator(func, *a, **k):
    def inner(*args, **kwargs):
        print('执行前')
        ret = func(*args, **kwargs)
        print('执行后')
        return ret
    return inner

注:这种装饰器不能使用语法糖来装饰函数,只能通过包裹被装饰函数来实现

如下实现一个偏函数:

def partial(func, *a, **k):
    def inner(*args, **kwargs):
        ret = func(*a, *args, **k, **kwargs)
        return ret
    return inner


def add(a, b):
    print(a + b)


add = partial(add, 1)
add(b=2)	# 3

方式三:类

class decorator(object):
    def __init__(self, name):
        self.name = name
    
    def __call__(self, func):
        def inner(*args, **kwargs):
            print('执行前')
            ret = func(*args, **kwargs)
            print('执行后')
            return ret
        return inner

方式四:偏函数+lambda

from functools import partial

def decorator(name, func, *args, **kwargs):
    print('执行前')
    ret = func(*args, **kwargs)
    print('执行后')
    return ret


new_decorator = lambda name: lambda func: partial(decorator, name, func)
posted @ 2021-08-08 18:09  D-U  阅读(98)  评论(0)    收藏  举报