Python装饰器

装饰器是一种用于封装函数或类的代码工具。它显式的将封装器应用到函数或类上,从而使它们选择加入到装饰器的功能中。闭包

装饰器究其本质是一个接受可调用函数的可调用函数,并返回一个可调用函数。装饰器是一个函数,该函数接受被装饰的函数做为其位置参数,装饰器经过使用该参数来执行某些操做,而后返回原始参数或一些其余的调用。模块化

看下面的代码,是一个简单的装饰器:函数

1 def decorated_by(func):
2     func.__doc__ += '\nDecorated by decorated_by.'
3     return func
4 
5 def add(x, y):
6     return x + y
7 
8 add = decorated_by(add)

在上面这段代码中,decorated_by是装饰器,add是被装饰的函数,代码的做用就是修改了add函数的__doc__属性。工具

将被装饰函数应用装饰器通常写做:spa

1 @decorated_by
2 def add(x, y):
3     return x + y

装饰器实现的原理是什么呢?装饰器之因此可以实现是因为Python的闭包。调试

再来看一段代码:code

def func(a, b):
    x=a
    y=b
    def add():
        z=4
        return x+y+z
    return add

>>>add =  func(1, 2)
>>>add()
7

add是func的内部函数,在add的局部做用域中能够直接访问func局部做用域中定义的x, y变量。简单的说,这种内部函数可使用外部函数变量的行为,叫作闭包。
再来看一段代码:blog

 1 def dec(func):
 2     def in_dec(*arg):
 3         if len(arg) == 0:
 4             return 0
 5         for val in arg:
 6             if not isinstance(val, int):
 7                 return 0
 8         return func(*arg)
 9     return in_dec
10 
11 @dec
12 def my_sum(*arg):
13     return sum(arg)
14 
15 @dec
16 def my_average(*arg):
17     return sum(arg) / len(arg)
18 
19 print (my_sum(1,2,3,4,5,6)) (等同于mysum = dec(my_sum); mysum(1,2,3,4,5,6))
20 print (my_average(1,2,3,4,5,6)) 

咱们来分析一下整个的调用过程:作用域

首先当遇到语法糖@dec时,调用dec,而后它会返回in_dec,因为my_sum做为一个参数传入dec,所以它做为闭包内的变量被in_dec所使用,这时my_sum被从新赋值my_sum = in_dec,因此咱们调用my_sum时实际上是调用了in_dec,而in_dec有调用了原来的my_sum。以上就是装饰器所作的事情,其实就是Python闭包的一种应用。class

使用装饰器的好处在于:一、使代码能够复用。从上边的代码能够看出,装饰器的主要做用是对参数进行检验,所以该装饰器能够用于全部有相似参数检验需求的函数,避免了大量冗余代码;二、因为装饰器是显式的,它们在全部须要它们的被调用函数中使用。所以这对于可读性颇有价值,从而使调试也更加方便。当一个装饰器编写的足够好时,它们是模块化且清晰明确的。

相关文章
相关标签/搜索