装饰器原理
def decorator(func):
def wrap_function():
print("函数执行前")
func()
print("函数执行后")
return wrap_function
def operation(x):
print(x+x)
if __name__=="__main__":
decorator(operation(1))
从上面的代码可以知道装饰器就是用来修改其他函数的功能的,这也符合python的哲学简单优雅。
函数装饰器
下面通过函数装饰器实现日志记录
函数装饰器不带参数但目标函数带参数
from functools import wraps
def my_logger(func):
@wraps(func)
def record(*args, **kwargs):
print(func.__name__ + "被执行")
return func(*args, **kwargs)
return record
@my_logger
def operation(x):
return x + x
if __name__=="__main__":
operation(1)
operation被执行
函数装饰器和被装饰函数都带参数
from functools import wraps
def my_logger(logfile="test.log"):
def decorator(func):
@wraps(func)
def record(*args, **kwargs):
log_string = func.__name__ + "被执行"
with open(logfile, 'a') as opened_file:
opened_file.write(log_string + '\n')
return func(*args, **kwargs)
return record
return decorator
@my_logger(logfile="my.log")
def operation(x):
return x + x
if __name__=="__main__":
operation(1)
类装饰器
类装饰器的实现,必须实现call和init两个内置函数。在实现类装饰器的时候,使用init()方法来接收被装饰函数,使用call()方法来添加装饰器要实现的功能,并在call()方法中执行和返回被装饰函数。
下面通过类装饰器实现权限判断
类装饰器和被装饰的函数都不带参数
函数 | 解释 |
---|---|
init | 接收被装饰函数,而是接收传入参数 |
call | 接收被装饰函数的参数,实现装饰逻辑; |
class BasePermissionDecorator(object):
def __init__(self,func):
self.func=func
def __call__(self, *args, **kwargs):
if self.check_permission():
print(f'权限通过开始运行函数{self.func.__name__}')
return self.func(*args,**kwargs)
else:
return print('权限未通过!!!')
def check_permission(self):
raise NotImplementedError()
class permit_all(BasePermissionDecorator):
def check_permission(self):
print("检查权限")
print("放开所有权限")
return True
@permit_all
def upload_file():
print('上传文件')
if __name__=="__main__":
upload_file()
运行结果如下:
检查权限
放开所有权限
权限通过开始运行函数upload_file
上传文件
类装饰器带参数但被装饰的函数不带参数
函数 | 解释 |
---|---|
init | 不接收被装饰函数,而是接收类装饰器的参数 |
call | 接收被装饰函数。实现装饰逻辑,返回被装饰函数 |
class BasePermissionDecorator(object):
def __init__(self,permission_name=""):
self.permission_name=permission_name
def __call__(self,func,*args,**kwargs):
if self.check_permission():
print(f'权限通过开始运行函数{func.__name__}')
return func
else:
return lambda:print('权限未通过!!!')
def check_permission(self):
raise NotImplementedError
class permit_all(BasePermissionDecorator):
def check_permission(self):
print(f"检查{self.permission_name}权限")
print(f"放开所有{self.permission_name}权限")
return True
@permit_all(permission_name="超级管理员")
def upload_file():
print('上传文件')
if __name__=="__main__":
upload_file()
当check_permission返回True时返回如下内容:
检查超级管理员权限
放开所有超级管理员权限
权限通过开始运行函数upload_file
上传文件
当check_permission返回False时返回如下内容:
检查超级管理员权限
放开所有超级管理员权限
权限未通过!!!
类装饰器不带参数但被装饰的函数带参数
函数 | 解释 |
---|---|
init | 接收被装饰函数 |
call | 接收被装饰函数的参数,实现装饰逻辑,返回执行被装饰函数的执行的结果 |
class BasePermissionDecorator(object):
def __init__(self,func):
self.func=func
def __call__(self,*args,**kwargs):
self.role=args[0]
if self.check_permission():
print(f'权限通过开始运行函数{self.func.__name__}')
return self.func(*args,**kwargs)
else:
return print('权限未通过!!!')
def check_permission(self):
raise NotImplementedError
class permit_all(BasePermissionDecorator):
def check_permission(self):
print("检查权限")
if self.role=="admin":
print(f"该用户具有{self.role}权限")
return True
else:
return False
@permit_all
def upload_file(role):
print('上传文件')
if __name__=="__main__":
upload_file("admin")
运行结果如下:
检查权限
该用户具有admin权限
权限通过开始运行函数upload_file
上传文件
类装饰器带参数和被装饰函数都带参数
函数 | 解释 |
---|---|
init | 不接收被装饰函数,接受类装饰器的参数 |
call | 接收被装饰函数的参数以及参数,实现装饰逻辑,返回一个新的函数; |
from functools import wraps
class BasePermissionDecorator(object):
def __init__(self, permit_role):
self.permit_role = permit_role
def __call__(self, func):
@wraps(func)
def wrapper(*args, **kwargs):
self.user_role = args[0]
if self.check_permission():
print(f'权限通过开始运行函数{func.__name__}')
return func(*args, **kwargs)
else:
print("权限不匹配")
return wrapper
def check_permission(self):
raise NotImplementedError
class permit_all(BasePermissionDecorator):
def check_permission(self):
print("检查权限")
if self.user_role == self.permit_role:
print(f"该用户具有{self.permit_role}权限")
return True
else:
return False
@permit_all("admin")
def upload_file(user_role):
print('上传文件')
if __name__ == "__main__":
upload_file("admin")
执行下面的语句:
if __name__=="__main__":
upload_file("admin")
运行结果如下:
检查权限
该用户具有admin权限
权限通过开始运行函数upload_file
上传文件
执行下面的语句:
if __name__=="__main__":
upload_file("admin11")
运行结果如下:
检查权限
权限不匹配