python的函数装饰器和类装饰器 2021年02月04日 未雨晴空 0评论 36阅读 0喜欢 阅读模式 隐藏边栏 显示边栏 # 装饰器原理 ```Python 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的哲学简单优雅。 # 函数装饰器 下面通过函数装饰器实现日志记录 ## 函数装饰器不带参数但目标函数带参数 ```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) ``` ```python operation被执行 ``` ## 函数装饰器和被装饰函数都带参数 ```python 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____ | 接收被装饰函数的参数,实现装饰逻辑; | ```python 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() ``` 运行结果如下: ```python 检查权限 放开所有权限 权限通过开始运行函数upload_file 上传文件 ``` ## 类装饰器带参数但被装饰的函数不带参数 | 函数 | 解释 | | ------------ | -------------------------------------------- | | ____init____ | 不接收被装饰函数,而是接收类装饰器的参数 | | ____call____ | 接收被装饰函数。实现装饰逻辑,返回被装饰函数 | ```Python 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时返回如下内容: ```python 检查超级管理员权限 放开所有超级管理员权限 权限通过开始运行函数upload_file 上传文件 ``` 当check_permission返回False时返回如下内容: ```python 检查超级管理员权限 放开所有超级管理员权限 权限未通过!!! ``` ## 类装饰器不带参数但被装饰的函数带参数 | 函数 | 解释 | | ------------ | ------------------------------------------------------------ | | ____init____ | 接收被装饰函数 | | ____call____ | 接收被装饰函数的参数,实现装饰逻辑,返回执行被装饰函数的执行的结果 | ```python 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") ``` 运行结果如下: ```python 检查权限 该用户具有admin权限 权限通过开始运行函数upload_file 上传文件 ``` ## 类装饰器带参数和被装饰函数都带参数 | 函数 | 解释 | | ------------ | ------------------------------------------------------------ | | ____init____ | 不接收被装饰函数,接受类装饰器的参数 | | ____call____ | 接收被装饰函数的参数以及参数,实现装饰逻辑,返回一个新的函数; | ```python 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") ``` 执行下面的语句: ```python if __name__=="__main__": upload_file("admin") ``` 运行结果如下: ```python 检查权限 该用户具有admin权限 权限通过开始运行函数upload_file 上传文件 ``` 执行下面的语句: ```python if __name__=="__main__": upload_file("admin11") ``` 运行结果如下: ```python 检查权限 权限不匹配 ``` © 著作权归作者所有,欢迎转载,转载请说明出处:未雨晴空博客,谢谢理解! 喜欢 打赏 分享 上一篇 下一篇 发表评论 取消回复 电子邮件地址不会被公开。 表情 请输入以http或https开头的URL,格式如:https://oneisall.top 提交评论