装饰器(decorator):
1,本质是函数,也是通过def编写的,用来装饰其他函数。即为其他函数添加附加功能
2,原则:(1):不能修改被装饰函数的源代码
(2):本能修改被装饰函数的调试方式。
3,实现装饰器知识储备:
(1):函数即变量
(2);高阶函数
(3);嵌套函数
高阶函数+嵌套函数 ——》实现装饰器
以下通过实例来一步一步的来引入装饰器
首先:高阶函数
a):把一个函数名当做实参传递给个另一个函数(可以达到不修改被装饰的函数源代码的情况下为其添加新功能)
b):返回值中包含函数名(实现了不改变函数的调用方式)
import time def deco(func): start_time=time.time() func() stop_time=time.time() print 'the time of func is %s'%(stop_time-start_time) def bar(): time.sleep(3) print 'this is the bar' deco(bar)
绿色部分是装饰函数实现的一些功能,红色为被装饰函数,通过 deco(bar)来调用,这里没有对源代码修改,但修改了调用方式,所以并不是装饰器
import time def deco(func): print 'in the deco' return func def bar(): time.sleep(3) print 'this is the bar'
bar=deco(bar) bar()
先把bar函数的内存地址赋值给deco函数的形参,把deco函数的返回值赋值给bar变量,然后进行调用bar(),
这里通过在deco函数中添加 return 语句,实现了不修改被装饰函数的调用方式。
其次:嵌套函数:即在一个函数的函数体内去用def定义一个函数
foo函数内部嵌套一个bar函数,如果在外部对bar函数进行调用,会出错,因为函数即变量,内部定义的函数,相当于一个局部变量,只在内部有效,所以在外部调用时无效的。
最后:高阶函数+嵌套函数 ——》实现装饰器:
import time def timmer(func): def deco(): start_time = time.time() func() stop_time = time.time() print('the time of func is %s' %(stop_time - start_time)) return deco def bar(): time.sleep(3) print 'this is the bar' bar=timmer(bar) bar()
函数deco嵌套与timmer函数内部,通过外层的timmer函数来返回deco函数的内存地址。
在调用时, bar=timmer(bar),是吧bar函数的内存地址赋值给timmer的形参,然后timmer函数的返回值(即deco函数的内存地址)赋值给变量bar,然后执行的语句bar(),其实就是在调用deco函数。
小型装饰器实例:
user='chenna' passwd='ccc123' def auth (func): def deco(*args,**kwargs): username=raw_input('username:').strip() password=raw_input('passward:').strip() if user==username and passwd==password: func(*args,**kwargs) else: exit('invalid username or password') return deco def index(): print 'welcome to index page' @auth def home(): print 'welcome to home page' @auth def bbs(): print 'welcome to bbs page' index() home() bbs()
“@+装饰器函数名称”=“被装饰器函数名=装饰器名(被装饰器名)”,并且“@+装饰器名”放在被装饰函数的头