闭包

要想了解装饰器,首先要了解一个概念,闭包。什么是闭包,一句话说就是,在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了。光说没有概念,直接上一个例子。

  1. def outer(x):
  2. def inner(y):
  3. return x + y
  4. return inner
  5. print(outer(6)(5))
  6. # 打印
  7. 11

在outer函数内,又定义了一个inner函数,并且inner函数又引用了外部函数outer的变量x,这就是一个闭包了。在输出时,outer(6)(5),第一个括号传进去的值返回inner函数,其实就是返回6 + y,所以再传第二个参数进去,就可以得到返回值,6 + 5。

装饰器

其实装饰器就是一个闭包,装饰器是闭包的一种应用。什么是装饰器呢,简言之,python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。使用时,再需要的函数前加上@demo即可。

  1. def debug(func):
  2. def wrapper():
  3. print("[DEBUG]: enter {}()".format(func.__name__))
  4. return func()
  5. return wrapper
  6. @debug
  7. def hello():
  8. print('hello')
  9. hello()
  10. --------------------
  11. >>>>[DEBUG]: enter hello()
  12. >>>>hello

例子中的装饰器给函数加上一个进入函数的debug模式,不用修改原函数代码就完成了这个功能,可以说是很方便了。

带参数的装饰器

上面例子中的装饰器是不是功能太简单了,那么装饰器可以加一些参数吗,当然是可以的,另外装饰的函数当然也是可以传参数的。

  1. def logging(level):
  2. def outwrapper(func):
  3. def wrapper(*args, **kwargs):
  4. print("[{0}]: enter {1}()".format(level, func.__name__))
  5. return func(*args, **kwargs)
  6. return wrapper
  7. return outwrapper
  8. @logging(level="INFO")
  9. def hello(a, b, c):
  10. print(a, b, c)
  11. hello("hello,","good","morning")
  12. -----------------------------
  13. >>>[INFO]: enter hello()
  14. >>>hello, good morning

如上,装饰器中可以传入参数,先形成一个完整的装饰器,然后再来装饰函数,当然函数如果需要传入参数也是可以的,用不定长参数符号就可以接收,例子中传入了三个参数。