python进阶—装饰器Decorator

python装饰器是在函数调用之上的修饰,这些修饰是在声明或者定义一个函数的时候进行设置的。同时,装饰器是一个返回函数对象的高级函数。装饰器的语法是以@开头的,而后是装饰器函数的名字以及可选的参数,而后是装饰器要修饰的函数以及该函数的可选参数,主要是以下形式:

@decorator(dec_opt_args)
def func2Bdecorator(func_opt_args):
......

1 装饰器与函数类型

装饰器类型

装饰器有两种形式,无参decorator以及有参decorator:
无参decorator
生成一个新的经过装饰的函数,并用这个经过装饰的函数代替原函数
有参decorator
装饰函数首先处理传入的decorator参数,并生成一个新的装饰器函数,然后使用这个装饰器函数对要被装饰的函数进行装饰

函数类型

同时函数又分为有参和无参两种
无参函数
对于无参数的函数,并没有什么需要特别注意的地方
有参函数
因为传入装饰器的函数是不定的,也就是说传入的参数也是不定的,为了使装饰器能对所有参数类型的函数进行处理,装饰器中函数的参数有特殊处理,接下来会介绍

2 无参装饰器-无参函数

def decorator_func(func):
    def handle():
        print "the function of %s begin ..." %func.__name__
        func()
        print "the function of %s end !" %func.__name__
    return handle

@decorator_func
def say():
    print "hello decorator!"

say( )
print say.__name__

上述代码最后调用say函数的输出如下:

the function of say begin ...
hello decorator!
the function of say end!
handle

decorator_func是一个装饰器(decorator),返回一个函数对象。上述代码中,在定义say函数前加上了@decorator_func之后,虽然say( )函数还是存在的,但是say变量指向了由decorator_func返回的handle函数对象,于是在上述代码的最后打印say的函数名的输出结果是handle而不是say

3 无参装饰器-有参函数

当需要修饰的函数带有参数时,装饰器的定义跟上述无参函数有一定的区别,主要为了让装饰器可以应对具有参数不同的各种函数

def decorator_func(func):
    def handle(*args, **kwargs):
        print "the function of %s begin ..." %func.__name__
        func(*args, **kwargs)
        print "the function of %s end !" %func.__name__
    return handle

@decorator
def say(name = "world"):
    print "hello %s!" %name

4 有参装饰器-无参函数

当装饰器带有参数,也就是在原来装饰器的基础上再做一层封装。代码实现如下:

def decomaker_func(text):
    def decorator_func(func):
        def handle():
            print "%s-->%s()!" %(text, func.__name__)
            func()
        return handle
    return decorator_func

@decomaker_func("haha")
def say():
    print "hello, decomaker!"

say()

上述代码的输出:

haha-->say()
hello, decomaker!

因装饰器自身带有参数,于是将其称之为decomaker,也就是上述定义中的第一层函数decomaker_func,它的作用是返回一个decorator也就是第二层函数decorator_func,这层函数的作用就是将封装好的handle函数赋值给say变量。

5 有参装饰器-有参函数

def decomaker_func(text):
    def decorator_func(func):
        def handle(*args, **kwargs):
            print "%s-->%s(*args, **kwargs)!" %(text, func.__name__)
            func(*args, **kwargs)
        return handle
    return decorator_func

@decomaker_func("haha")
def say(name = "decomaker"):
    print "hello, %s!" %name

say()

输出:

haha-->say(*args, **kwargs)
hello, decomaker!

6 给函数装饰多个装饰器

当一个函数由多个装饰器进行装饰时,其装饰过程是有固定的顺序的,比如如下的形式:

@d1
@d2(args)
@d3
def f():

等价于:

f = d1(d2(args)(d3(f)))

你可能感兴趣的:(python进阶—装饰器Decorator)