1. 程式人生 > 其它 >裝飾器的各種實現方式

裝飾器的各種實現方式

無引數裝飾器

方式一:閉包

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)