学设计模式中有个装饰模式, 用 java 实现起来不是很难, 但是远远没有 python 简单, 难怪越来越火了!
这里就简单讨论下 python 的几种装饰模式:
一 无参装饰器:
- # 装饰器
- import time
- # 装饰器, 记录函数运行时间
- def decorator01(fun):
- def wapper():
- stime = time.time()
- fun()
- etime = time.time()
- print("fun run time is {TIME}".format(TIME=etime - stime))
- return wapper # 必须要返回一个函数的内存地址
- # 使用装饰器装饰某个函数, 等价于 test01=decorator01(test01),
- # 即将 test01 实际引用变成 wapper 函数内存地址, 所以执行 test01 实际是执行 wapper
- @decorator01
- def test01():
- time.sleep(2)
- print("test01 is running")
- test01() # 不修改代码和调用方式, 实现添加记录时间功能
二 函数带参装饰器:
- # 装饰器
- import time
- # 装饰器, 记录函数运行时间
- def decorator01(fun):
- def wapper(*args, **kwargs): # 使用非固定参数, 无论参数是什么, 都可以传递进来
- stime = time.time()
- fun(*args, **kwargs)
- etime = time.time()
- print("fun run time is {TIME}".format(TIME=etime - stime))
- return wapper # 必须要返回一个函数的内存地址
- # test01() = wapper(), 所以装饰器加参数是给嵌套函数加参数
- @decorator01
- def test01(args1):
- time.sleep(2)
- print("参数是 {NAME}".format(NAME=args1))
- test01("侯征") # 不修改代码和调用方式, 实现添加记录时间功能
三 装饰器本身带参数的装饰器:
- # 装饰器
- import time
- # 如果装饰器有参数, 最外层是装饰器的参数
- def decorator01(*args, **kwargs):
- print("装饰器参数:", *args, **kwargs)
- def out(fun): #第二层才是接受的函数
- def wapper(*args, **kwargs): # 使用非固定参数, 无论参数是什么, 都可以传递进来
- stime = time.time()
- fun(*args, **kwargs)
- etime = time.time()
- print("fun run time is {TIME}".format(TIME=etime - stime))
- return wapper # 必须要返回一个函数的内存地址
- return out # 要返回装饰函数的内存地址
- # 装饰器本身带参数, 此时 decorator01(arg)=out, 即相当于 @out 装饰 test01, 所以 test01=out(fun)=wapper
- @decorator01(1)
- def test01(args1):
- time.sleep(2)
- print("参数是 {NAME}".format(NAME=args1))
- test01("侯征") # 不修改代码和调用方式, 实现添加记录时间功能
这种一开始挺难理解的, 但是只要记住一点,@语法糖装饰器的作用就是 给被装饰的函数重新赋一个函数的内存地址, 即装饰器内部定义的那个
和你直接 fun01=decorator(fun), 然后 fun01() 是一样的, 只是这样写不用改变原来调用方式
- @decorator
- def fun():
即就是 fun=decorator(fun) 所以, 当装饰器有参数时, 还需要返回一个函数, 这个函数才是用来装饰作用的, decorator(1)=out, 即 fun=out(fun) !!
所以外面再包一层就行了, 其实就相当于 @decorator(1)=@out, 即 decorator(1)=out , 实际装饰器时 out, 只不过 decorator(1) 返回了一个 out 这样理解就简单多了 , 无参的 @就是起赋值作用
来源: http://www.bubuko.com/infodetail-2871742.html