|
Python 装饰器
python装饰器的本质是: 仅以一个函数为参数,并返回一个函数。 且看以下案例:- def decorator(f):
- print(f.__name__)
- return f
- # 1
- @decorator
- def fun():
- print("run fun")
- # 2
- fun = decorator(fun)
复制代码 以上两种写法是等价的;装饰器函数会在被装饰的函数 定义完成时执行。
装饰器优点:
- 不会改变被装饰函数的调用
- 不用修改被装饰函数的代码
根据使用场景装饰器可以分为几种:
一次性装饰器
一次性装饰器;不对被装饰函数进行任何操作,原样返回被装饰的函数;仅在被装饰函数定义时进行操作。- funcs = []
- def decorator(f):
- funcs.append(f) # 将函数保存到全局list中去
- return f
- @decorator
- def fun():
- print("run fun")
复制代码 包装装饰器
包装装饰器;一般是在被装饰函数执行前后做一些额外的操作,或者对被装饰函数计算的结果进行操作。- import time
- def decorator(f):
- def wrapper(*args, **kwds): # 不确定被装饰函数的参数,使用万能形参
- t1 = time.time()
- result = f(*args, **kwds) # 执行被装饰函数
- t2 = time.time()
- print(f.__name__, "执行耗时", t2-t1)
- return result
- return wrapper
- @decorator
- def fun():
- time.sleep(2)
- print("run fun")
- # fun = decorator(fun)
- # 此时 fun 已经变成了 wrapper 函数;已经被decorator返回的wrapper覆盖
复制代码 配置装饰器
即有带参数的装饰器,此装饰器可能是为了给被装饰函数提供额外的信息;或者需要用户自己添加配置。
我们只看wrapper函数是不是和上文的一次性装饰器一样呢- def decorator(name):
- def wrapper(f):
- f.name = name
- return f
- return wrapper
- @decorator("fun1")
- def fun():
- print("run fun")
- # fun = decorator("fun1")(fun)
- print(fun.name)
- fun()
复制代码 配置包装装饰器
配置包装装饰器,即有装饰器配置项和修改被包装函数执行流程的装饰器;- import time
- def decorator(name): # 配置选项
- def setname(f): # 包装被装饰的函数
- f.name = name # 闭包获取 配置选项
- def wrapper(*args, **kwds): # 返回的最终函数
- t1 = time.time()
- result = f(*args, **kwds) # 执行被包装的函数
- t2 = time.time()
- print(f.name, "执行耗时", t2-t1)
- return result
- return wrapper
- return setname
- @decorator("fun1")
- def fun():
- print("run fun")
复制代码 类装饰器
@decorator本质是一次函数调用;对应到类上就是__init__()调用;即类的实例化。如果类实现了__call__()方法,类的实例对象就可以像函数一样调用。- class Decorator:
- def __init__(self, name):
- self.name = name
-
- def __call__(self, f):
- self.f = f
- return self.wrapper
-
- def wrapper(self, *args, **kwds):
- print(self.name)
- return self.f(*args, **kwds)
- @Decorator("name")
- def fun():
- print("run fun")
复制代码 装饰类的装饰器
- def decorator(cls):
- def wrapper(*args, **kwds):
- obj = cls(*args, **kwds)
- return obj
- return wrapper
- @decorator
- class Test:
- def __init__(self):
- pass
- print(Test)
- print(Test())
- # <function decorator.<locals>.wrapper at 0x7fd9ecba5280>
- # <__main__.Test object at 0x7fd9ecc22550>
复制代码 多层装饰器
- def a(f):
- print("a 装饰器执行")
- def _a():
- print("函数执行 调用_a 装饰器")
- return f()
- return _a
- def b(f):
- print("b 装饰器执行")
- def _b():
- print("函数执行 调用_b 装饰器")
- return f()
- return _b
-
- def c(f):
- print("c 装饰器执行")
- def _c():
- print("函数执行 调用_c 装饰器")
- return f()
- return _c
- @a
- @b
- @c
- def fun():
- print("fun run")
- # fun = a( b( c(fun )) )
- fun()
- # -----程序输出—-----
- # c 装饰器执行
- # b 装饰器执行
- # a 装饰器执行
- # 函数执行 调用_a 装饰器
- # 函数执行 调用_b 装饰器
- # 函数执行 调用_c 装饰器
- fun run
复制代码 有什么建议意见请留言讨论
谢谢观看
浪费了你人生中的几秒真的很抱歉(≧ ﹏ ≦)
来源:https://www.cnblogs.com/main-warma/p/17938028
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|