净心诀---python3装饰器

python3装饰器

装饰器作用

简单理解:可以为已有函数添加额外功能

例:

已有2个函数如下

1 def MyFunc1():
2     print("This is a print function1")
3 
4 
5 def MyFunc2():
6     print("This is a print function2")

需求:现想要在函数执行前打印类似(开始使用XXX功能)

不用装饰器方式:

1 def MyFunc1():
2     print("开始使用MyFunc1功能")
3     print("This is a print function1")
4 
5 
6 def MyFunc2():
7     print("开始使用MyFunc2功能")
8     print("This is a print function2")

调用函数时输出:

思考:如果有很多很多的函数,那么每个函数中都要修改(而且这需要在已有函数内部去修改,部分情况下是不允许修改已有函数的),这个方式显然不可靠

采取装饰器的方式做

装饰器模板(写法)

1 def ShowFunction(func):
2     def inner(*args, **kwargs):
3         # 这里写函数执行前的功能
4         ret = func(*args, **kwargs)
5         return ret        
6     return inner

利用上述装饰器模板,来写一个上述需求的装饰器

 1 # 这是一个装饰器
 2 def ShowFunction(func):
 3     def inner(*args, **kwargs):
 4         name = func.__name__
 5         print("开始使用%s功能" %name)
 6         ret = func(*args, **kwargs)
 7         return ret        
 8     return inner
 9 
10 
11 @ShowFunction    # @加函数名  这种形式就是使用某个装饰器的写法
12 def MyFunc1():
13     print("This is a print function1")
14 
15 @ShowFunction
16 def MyFunc2():
17     print("This is a print function2")
18 
19 
20 MyFunc1()
21 MyFunc2()

效果如下:

 现在基本上就能满足上述需求

思考:有时候不是所有的装饰器都是永久装饰函数的,在某些情况下我们会希望装饰器不生效,此时需要用到带有参数的装饰器

此时我们一般会在装饰器外部在套一个函数,来接受一个Flag,在内部用这个Flag来判断是否生效装饰器

 1 # 现需要在调用每个函数前说明这是哪个函数,用到带装饰装饰器(可控制是否使装饰器生效)
 2 from functools import wraps
 3 
 4 # 这是一个装饰器
 5 Flag = 1
 6 def FuncWrap(Flag):
 7     def ShowFunction(func):
 8         @wraps(func)    #使外部函数调用函数属性时,不被装饰器影响
 9         def inner(*args, **kwargs):
10             if Flag:
11                 name = func.__name__
12                 print("开始使用%s功能" %(name))
13                 ret = func(*args, **kwargs)
14             else:
15                 ret = func(*args, **kwargs)    
16             return ret        
17         return inner        
18     return ShowFunction
19 
20 
21 
22 @FuncWrap(Flag)    # 等于写法-->MyFunc1 = ShowFunction(MyFunc1)
23 def MyFunc1():
24     print("This is a print function1")
25 
26 @FuncWrap(Flag)
27 def MyFunc2():
28     print("This is a print function2")
29 
30 # print(MyFunc1.__name__)
31 MyFunc1()
32 MyFunc2()

我们可以修改Flag的值1(生效)或0(不生效)

扩展:多个装饰器共同装饰一个函数

 1 # 这是一个装饰器1
 2 def Wrap1(func):
 3     def inner(*args, **kwargs):
 4         print("start装饰器1")
 5         ret = func(*args, **kwargs)
 6         print("end装饰器1")
 7         return ret        
 8     return inner
 9 
10 # 这是一个装饰器2
11 def Wrap2(func):
12     def inner(*args, **kwargs):
13         print("start装饰器2")
14         ret = func(*args, **kwargs)
15         print("end装饰器2")
16         return ret        
17     return inner
18 
19 @Wrap1
20 @Wrap2
21 def MyFunc1():
22     print("This is a print function1")
23 
24 MyFunc1()

关于多装饰器现象(记住即可):

原文地址:https://www.cnblogs.com/zakker/p/12047878.html