装饰器
装饰器:
本质上是函数,(装饰其他函数)就是为其他函数添加附加功能。
原则:
1,不能修改被装饰的函数的源代码。(在不修改被装饰函数代码的情况下为其添加功能)
2,不能修改被装饰的函数的调用方式。 (不修改函数的调用方式)
实现装饰器知识储备:
1,函数即“变量”。
2,高阶函数。
a:把一个函数名当做实参传给另个一函数。
b:返回值中包含函数名。
3,嵌套函数。
在一个函数体内,用def去声明一个函数。(这里要跟调用分开)
高阶函数+嵌套函数=装饰器
例子1
import time def timer(func): def deco(): start_time =time.time() func() stop_time=time.time() print('test time %s'%(stop_time-start_time)) return deco @timer def test1(): time.sleep(3) print('in test1') test1()
例子2
import time def timer(func): def deco(*args,**kwargs): start_time =time.time() func(*args,**kwargs) stop_time=time.time() print('test time %s'%(stop_time-start_time)) return deco @timer #test1=timer(test1)=deco deco()=test1() def test1(): time.sleep(3) print('in test1') @timer def test2(name):#test2=timer(test2)=deco deco(name)=test2(name) print('in test2',name) test1() test2('qiangql')
例子3
import time user,passwd ='qiangql','1234' #本地的用户名密码 def auth(func): def wrapper(*args,**kwargs): username=input('username:').strip() password=input('password').strip() if user == username and passwd == password: print('\033[32;1muser has passed authentication\033[0m') func(*args,*kwargs) #用户名密码符合开始执行函数 else: exit('\033[31;1mInvalid username or password\033[0m') return wrapper 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()
例子4
多种认证方式
import time user,passwd ='qiangql','1234' def auth(auth_type): print('查看auth处auth_type',auth_type) def outwrapper(func): def wrapper(*args,**kwargs): if auth_type =='bendi': username=input('username:').strip() password=input('password').strip() if user == username and passwd == password: print('\033[32;1muser has passed authentication\033[0m') func(*args,*kwargs) #用户名密码符合开始执行函数 else: exit('\033[31;1mInvalid username or password\033[0m') elif auth_type == 'waibu': print('waibu') return wrapper return outwrapper def index(): print('welcome to index page') @auth(auth_type='bendi') # def home(): print('welcome to home page') @auth(auth_type='waibu') def bbs(): print('welcome to bbs page') index() home() bbs()
需要加上断点慢慢理解
这里加下自己的理解
装饰器就是为了不改动原代码的情况下对程序的一种修改。
先定义一个函数名func,在原函数头顶上@函数名,例如@func,##### @func其实就把原函数名 改为func函数上的变量。。。这里有点说不清,看例子,@func 就是把下边的index变成了wwwww。
func里边在定义一个函数abc,这个函数里的内容就是你要‘装饰’的东西,也就是要增加的功能,最后return abc,这样如果调用func 最后return到abc,即可用到里边的功能
abc里边要要有原函数,在abc里边使用。即必须有wwwww(),其实就是index()。我就是这么瞎比理解的
例如
def func(wwwww):
def abc(*args,**kwargs):
wwwww()
return abc
@func #就是让index =wwwww
def index():
print('1111')
index()
def func(wwwww): def abc(): print('---') wwwww() print('456') return abc @func def index(): print('123') index()
还有一种复杂的装饰就是在@func 里边加参数
这样就需要在装饰器里边多加一层函数,然后给'他'return回来,增加判断。
我目前能理解的就这么多,以后用的多了,可能会慢慢熟悉。
def func(aaaaaaa):
def panduanAAA(wwwww)
def abc ()
print('------')
wwwww()
print('456')
renturn abc
renturn panduanAAA
@func(aaaaaaa=1)
def index
print('我等于1')
print('123')
def func(aaaaaaa): #传aaaaa的参数 def efg(wwwwww): #多加一层传wwww def abc(): if aaaaaaa == 1: print('--------') wwwwww() print('456') else: print('888') return abc return efg @func(aaaaaaa=1) def index(): print('我等于1') print('123') index()