python装饰器二
1、首先我们来看看一个函数作为参数传给另一个函数,如下所示,我们先定义一个函数,在定义另一个函数:
def firstfunc(): print 'my first func' 第一个函数def secondfunc(func): print('你开始调用 secondfunc') return func() 第二个函数

2、接下来我们把函数一作为参数传给函数二,看看是否可以输出结果
secondfunc(firstfunc)
我们可以看到输出结果:
你开始调用 secondfunc
my first func
具体如下图

3、接下来我们开始来写一个装饰器,步骤1,2中其实也就是一个装饰器原理实现函数了。接着我们按照一二步骤原理,完整的写一个装饰器
def my_decorator(myfunc):
def my_wrapper():
print('你已经进入 my_wrapper方法')
myfunc
print('调用my_wrapper方法 结束')
return my_wrapper
def myfunction():
print("你好装饰器")

4、我们开始使用步骤3中装饰器,如下:
print(myfunction()) #调用函数myfunctionmyfunction=my_decorator(myfunction()) #通过装饰器改写函数myfunction
输出结果如下:
你好装饰器
None
你已经进入 my_wrapper方法
调用my_wrapper方法 结束


5、由此可以看出python装饰器,封装了一个函数,然后用它希望的方法对函数进行处理,实际项目中我们使用装饰器通常是@XXXX的,下面我们试试用这种方法来使用装饰器
@my_decoratordef myfunction(): print("你好装饰器")myfunction
输出结果:
你已经进入 my_wrapper方法
调用my_wrapper方法 结束
可以看出装饰器已经起作用了


6、我们可以看看装饰器修改后的函数还是不是原来的函数,
@my_decorator
def myfunction():
print("你好装饰器")
myfunction()
print my_decorator.func_name
print myfunction.func_name
输出结果如下:
你已经进入 my_wrapper方法
你好装饰器
调用my_wrapper方法 结束
my_decorator
my_wrapper
可以看出myfunction函数名称被覆盖了,怎么办呢,继续下一步

7、为了解决6步骤中的问题我们需要引入python的functools wraps来解决问题,wraps接受一个函数,可以让我们访问它之前的属性,具体我们可以点开它查看它的属性,如下图所示:

8、我们开始使用wraps,如下所示我们将之前代码做修改:
from functools import wraps #增加def my_decorator(myfunc): @wraps(myfunc) #增加 def my_wrapper(): print('你已经进入 my_wrapper方法') myfunc() print('调用my_wrapper方法 结束') return my_wrapper@my_decoratordef myfunction(): print '你好装饰器'

9、最后我们调用步骤8中方法,看看输出是否是我们想要的
myfunction()print my_decorator.func_nameprint myfunction.func_name
输出结果:
你已经进入 my_wrapper方法
你好装饰器
调用my_wrapper方法 结束
my_decorator
myfunction 可以看出这是我们期望的结果。
