Python 装饰器
一、定义
器即函数
装饰即修饰,意指为其他函数添加新功能
装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象
实现装饰器:
装饰器=高阶函数+函数嵌套+闭包
二、原则:
1 、开放封闭原则:对扩展是开放的,对修改是封闭
2.1 装饰器的遵循的原则:1 不修改被装饰对象的源代码 2 不修改被调用对象的调用方式
三、目的
装饰器的目的是:在遵循1和2原则的前提,为其他新功能函数添加
四、定义位置
@装饰器名,必须写在被装饰对象的正上方,并且是单独一行
import time def timmer(func): # func=index def wrapper(): start=time.time() func() stop=time.time() print('run time is %s' %(stop-start)) return wrapper @timmer # index=timmer(index) def index(): time.sleep(3) print('welcome to index') @timmer # home=timmer(home) def home(): time.sleep(2) print('welcome to home page') index() home()
五、带参数的装饰器
无参装饰器版本 current_user={'user':None} def auth(func): def wrapper(*args,**kwargs): if current_user['user']: return func(*args,**kwargs) name=input('name: ').strip() password=input('password: ').strip() with open('db.txt', encoding='utf-8') as f: user_dic = eval(f.read()) if name in user_dic and password == user_dic[name]: res=func(*args,**kwargs) current_user['user']=name return res else: print('user or password error') return wrapper @auth #index=auth(index) index=wrapper def index(): print('from index') index() @auth def home(name): print('welcome %s' %name) index() #wrapper() home('egon')
#有参装饰器版本 current_user={'user':None} def auth(auth_type='file'): def deco(func): def wrapper(*args, **kwargs): if auth_type == 'file': if current_user['user']: return func(*args, **kwargs) name = input('name: ').strip() password = input('password: ').strip() with open('db.txt', encoding='utf-8') as f: user_dic = eval(f.read()) if name in user_dic and password == user_dic[name]: res = func(*args, **kwargs) current_user['user'] = name return res else: print('user or password error') elif auth_type == 'mysql': print('mysql') elif auth_type == 'ldap': print('ldap') else: print('not valid auth_type') return wrapper return deco @auth(auth_type='mysql') #@deco #index=deco(index) def index(): print('from index') @auth(auth_type='file') def home(name): print('welcome %s' %name) index() #wrapper() home('egon')
#带参数的装饰器 import time def timmer(func): #接受的参数 def wrapper(*args,**kwargs): #装饰的功能 start=time.time() #传入要执行的函数 res=func(*args,**kwargs) stop=time.time() print('run time is %s' %(stop-start)) return res return wrapper @timmer # index=timmer(index) #定义装饰器 def index(): time.sleep(3) print('welcome to index') return 123 @timmer # home=timmer(home)#定义装饰器 def home(name): time.sleep(2) print('welcome %s to home page' %name) # res=index() #res=wrapper() # print(res) res1=home('egon') #wrapper('egon')#调用 print(res1)
六、给闭包函数加注释
通过引用from functools import wraps 来进行加入注释说明
import time from functools import wraps def timmer(func): @wraps(func) def wrapper(*args,**kwargs): start=time.time() res=func(*args,**kwargs) stop=time.time() print('run time is %s' %(stop-start)) return res return wrapper @timmer # index=timmer(index) def index(): '''这是index函数''' time.sleep(3) print('welcome to index') return 123 print(index.__doc__) # print(help(index))