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)))