[python] 之 装饰器,, 装饰器本质上是一
[python] 之 装饰器,, 装饰器本质上是一
装饰器本质上是一个python函数,它可以让其它函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象。装饰器主要用于插入日志、性能测试、事务处理、缓存及权限校验等,解决代码重复使用。值得注意的是,内层函数保留(记忆)了外层函数的(参数)状态。
一、装饰器创建
装饰器的语法以@开头,接着是装饰器函数的变量名和可选参数,紧接着是被修饰函数的定义及被修饰函数的可选参数。
语法:
@decorator(dec_opt_args)
def fuc2Bdecorated(func_opt_args):
func_body
1 def dec1(func1): 2 def wrapper1(): 3 print(‘hello!‘) 4 return func1 5 return wrapper1 6 @dec1 7 def test(): 8 pass 9 10 test()11 #输出12 hello!
装饰器可以像函数一样堆叠起来,如下:
1 def dec1(func1): 2 def wrapper1(): 3 print(‘hello!‘) 4 return func1 5 return wrapper1 6 7 def dec2(func2): 8 def wrapper2(): 9 print (‘Pyhton!‘)10 return func211 return wrapper212 13 @dec214 @dec115 def test():16 pass17 if __name__ == ‘__main__‘:18 test()19 #输出20 Python!
此时,函数变量名test作为一个参数传递给了装饰器函数dec1,并返回wrapper1;然后wrapper1作为参数传递给了dec2,并返回了wrapper2;最后test()等价于wrapper2()的调用,即dec2(dec1(test()))。
二、有参数的函数装饰器
2.1 被修饰的函数含有参数
该函数等价于dec2(dec1(test(‘dec00‘)))
1 def dec1(func1): #func = test 2 def wrapper1(arg1): # arg1 = arg2 3 print(arg1+‘ + hello!‘) 4 return func1(arg1) #func1 = test 5 return wrapper1 6 7 def dec2(func2): #func2 = wrapper1 8 def wrapper2(arg2): # arg2 = ‘dec00‘ 9 print (arg2+‘ + Pyhton!‘)10 return func2(arg2) #wrapper1(arg2)11 return wrapper212 13 @dec214 @dec115 def test(t):16 print(t+‘ + test‘)17 if __name__ == ‘__main__‘:18 test(‘dec00‘)19 20 #输出21 dec00 + Pyhton!22 dec00 + hello!23 dec00 + test
2.2 装饰器函数含有参数
该函数首先执行dec2(‘dec2‘),返回dec21,然后整个函数等价于dec21(dec1(test01(‘dec01‘)))或者dec2(‘dec2‘)(dec1(test01(‘dec01‘))),请读者认真体会以上两种情况。
1 def dec1(func1): #func = test01 2 def wrapper1(arg1): 3 print(arg1+‘ + hello!‘) 4 return func1(arg1) 5 return wrapper1 6 7 def dec2(level): #level = ‘dec2‘ 8 def dec21(func2): #func2 = wrapper1 9 def wrapper2(arg2): #arg2 = ‘dec01‘10 print (level+‘ + ‘+arg2+‘ + Pyhton!‘)11 return func2(arg2) #func2 = wrapper112 return wrapper213 return dec2114 @dec2(‘dec2‘)15 @dec116 def test01(t):17 print(t +‘ + test01‘)18 if __name__ == "__main__":19 test01(‘dec01‘)20 #输出21 dec2 + dec01 + Pyhton!22 dec01 + hello!23 dec01 + test01
三、基于类的装饰器
根据装饰器语法及其运算性质,可知装饰器函数本身必须是可调用(callable)的,然后返回一个可调用(callable)对象。在Python中一般callable对象都是函数,但也有例外。只要某个对象重载了__call__()方法,那么这个对象就是callable的。
下面是可调用的类:
1 class P(object): 2 def __call__(self): 3 print (‘callable‘) 4 def func(self): 5 print (‘class‘) 6 7 i = P() 8 i.func() 9 i()10 11 #输出12 class13 callable
3.1 基于可调用的类,创建装饰器:
1 class P(object): 2 def __init__(self,func): 3 self.func = func 4 def __call__(self): 5 print (‘callable‘) 6 return self.func() 7 @P 8 def test(): 9 print(‘test‘)10 if __name__ == "__main__" : 11 test()12 #输出13 callable14 test
在上述函数调用过程中,类P是一个可调用的对象,类似于函数。上述装饰器执行等价于P(test())。
3.2 带参数的类装饰器
1 class P(object): 2 def __init__(self,level): 3 self.level = level # level = ‘level‘ 4 def __call__(self,func): # func = test 5 def wrapper(t): #t = ‘t‘ 6 print (self.level + ‘ + callable‘) 7 return func(t) # test(‘t‘) 8 return wrapper 9 @P(‘level‘)10 def test(t):11 print(‘test‘)12 if __name__ == "__main__" : 13 test(‘t‘)14 15 #输出16 level + callable17 test
此装饰器执行时,首先调用类P,初始化类并返回了函数变量名wrapper,此时该函数的参数,来源与被修饰的函数的参数,这一点和基于函数的装饰器是等同的。
[python] 之 装饰器
相关内容
- 【转】Python中的join()函数的用法,,【红色为转载后新增
- 【python】flask 开启 debug 模式,,方法一: 直接在ru
- 面试题:Python大小写转换,,小文:今天面试又搞砸
- python3 面向过程编程思想,函数综合应用,,应用:gre
- 【401】Python 求合数的所有质数因子,,对于这样的一个
- Python3网络爬虫(二):利用urllib.urlopen向有道翻译发送数
- Python中 list, numpy.array, torch.Tensor 格式相互转化,,1.1 l
- python_封装redis_list方法,,xshell 进入
- Python 技巧(三)—— list 删除一个元素的三种做法,
- python编程实现截屏操作,,由于工作内容的要求,
评论关闭