装饰器功能:
- 引入日志功能
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后清理功能
- 权限校验等场景
- 缓存
前一篇中写一个函数作为装饰器,其实在实际开发中,我们可能单独写一个类文件,作为装饰器,在需要的地方装饰,而不是到处在文件中写函数作为装饰器,比如权限校验,日志调用等。当然同样也可以用拦截器之类的做,这里主要说用类装饰器类做。
"""
装饰器函数其实是这样一个接口约束,它必须接受一个callable对象作为参数,然后返回一个callable对象。在Python中一般callable对象都是函数,
但也有例外。只要某个对象重写了 __call__() 方法,那么这个对象就是callable的。
"""
class Test1():
def __call__(self):
print('-----------测试call方法--------')
# t指向了Test这个对象
t = Test1()
# 当Test()这个对象覆写了__call__这个函数就可以用t()像调用函数一样调用__call__()
t()
print("-"*120)
class Authorize(object):
def __init__(self, func):
print("---初始化类---")
print("传入函数的名字: %s"%func.__name__)
self.__func = func
def __call__(self):
print("---判断该函数是否具有访问权限---")
if True:
print("有访问权限")
self.__func()
else:
print("没有访问权限")
print("权限判断结束")
#调用过程:
#1. 当用Authorize来装作装饰器对visitUser函数进行装饰的时候,首先会创建Authorize的实例对象
# 并且会把visitUser这个函数名当做参数传递到__init__方法中
# 即在__init__方法中的func变量指向了visitUser函数体
#2. visitUser函数相当于指向了用Authorize创建出来的实例对象
#3. 当在使用visitUser()进行调用时,就相当于让这个对象(),因此会调用这个对象的__call__方法
#4. 为了能够在__call__方法中调用原来visitUser指向的函数体,所以在__init__方法中就需要一个实例属性来保存这个函数体的引用
# 所以才有了self.__func = func这句代码,从而在调用__call__方法中能够调用到visitUser之前的函数体
# 简单理解装饰器@Authorize相当于 visitUser = Authorize(visitUser)
@Authorize
def visitUser():
print("----访问用户信息---")
visitUser()
执行结果:
-----------测试call方法--------
------------------------------------------------------------------------------------------------------------------------
---初始化类---
传入函数的名字: visitUser
---判断该函数是否具有访问权限---
有访问权限
----访问用户信息---
权限判断结束