装饰器写法一般分为装饰器方法与装饰器类,装饰器类的优势在于可以继承。

装饰器方法

#无参数装饰器方法
def func_decorator(func):
    #为了适应全部参数类型的函数
    #星号代表不定长度参数
    #单星号多个参数会是元组形式,双星号为字典形式
    def wrapper(*args, **kwargs):
        print('do decorate')
        func(*args, **kwargs)
        print('after return')

    return wrapper

#有参数装饰器方法
#需要再包一层传递装饰器参数
def func_decorator_with_args(level):
    def wrapper(func):
        def inner_wrapper(*args, **kwargs):
            print('do decorate')
            print('get level: ' + str(level))
            func(*args, **kwargs)
            print('after return')
        return inner_wrapper
    return wrapper


@func_decorator
def myFunc():
    print('myFunc')
    return

@func_decorator
def myFuncWithArgs(a,b):
    print('args: ' + str(a) + ' ' + str(b))
    return

@func_decorator
def myFuncWithMoreArgs(*args, **kwargs):
    print(args, kwargs)

@func_decorator_with_args(level = 1)
def myFuncTestDecoratorWithArgs():
    print('test decorator with args')

print('无参数函数:')
myFunc()
print('有函数参数:')
myFuncWithArgs(1, 2)
print('复杂函数参数:')
myFuncWithMoreArgs(1,2,a=1,b=2)
print('带参数装饰器:')
myFuncTestDecoratorWithArgs()

输出结果:

无参数函数:
do decorate
myFunc
after return
有函数参数:
do decorate
args: 1 2
after return
复杂函数参数:
do decorate
(1, 2) {'a': 1, 'b': 2}
after return
带参数装饰器:
do decorate
get level: 1
test decorator with args
after return

装饰器类

#装饰器类无参数
class class_decorator:

     def __call__(self, func):
        def wrapper(*args, **kwargs):
            print('do decorate')
            func(*args, **kwargs)
            print('after return')
        return wrapper

#装饰器类带参数
class class_decorator_with_args:
    level = 0
    def __init__(self, level):
        self.level = level

    def __call__(self, func):
        def wrapper(*args, **kwargs):
            print('do decorate')
            print('get level: ' + str(self.level))
            func(*args, **kwargs)
            print('after return')
        return wrapper

@class_decorator()
def myFunc():
    print('myFunc')
    return

@class_decorator()
def myFuncWithArgs(a,b):
    print('args: ' + str(a) + ' ' + str(b))
    return

@class_decorator()
def myFuncWithMoreArgs(*args, **kwargs):
    print(args, kwargs)

@class_decorator_with_args(level = 1)
def myFuncTestDecoratorWithArgs():
    print('test decorator with args')

print('无参数函数:')
myFunc()
print('有函数参数:')
myFuncWithArgs(1, 2)
print('复杂函数参数:')
myFuncWithMoreArgs(1,2,a=1,b=2)
print('带参数装饰器:')
myFuncTestDecoratorWithArgs()

输出结果:

无参数函数:
do decorate
myFunc
after return
有函数参数:
do decorate
args: 1 2
after return
复杂函数参数:
do decorate
(1, 2) {'a': 1, 'b': 2}
after return
带参数装饰器:
do decorate
get level: 1
test decorator with args
after return

上面使用的装饰器都是标注在方法上面,同样装饰器也可以在类上使用。

与Java注解的区别

装饰器是语法糖,本身具有逻辑功能,Java注解只是标记,不具有处理逻辑的能力。


guomz
16 声望1 粉丝

不求做完人,只求做凡人。