python进阶——装饰器Decorator

来源:互联网 发布:excel数据有效性 编辑:程序博客网 时间:2024/05/18 11:28

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_funcdef 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@decoratordef 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!" %namesay()

输出:

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

6 给函数装饰多个装饰器

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

@d1@d2(args)@d3def f():

等价于:

f = d1(d2(args)(d3(f)))
0 0
原创粉丝点击