python 设计模式-装饰器模式

2024-08-30 04:18

本文主要是介绍python 设计模式-装饰器模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

装饰器模式实现起来跟代理模式差多,其实可以是一样的,看你把它置于什么场景。代理模式侧重于隔离客户与被代理者,通过代理者控制访问被代理者的权限,而装饰器模式侧重于给被装饰的对象提供附加的功能,例如加上日志功能。python 语法层面就提供了装饰器,足以说明装饰器模式的重要性,这里我们就直接介绍python的装饰器吧。

先看看函数装饰器:

def work_wrapper(w):def func(*args, **kwargs):print('logging start ...')w(*args, **kwargs)print('logging end ...')return func@work_wrapper
def work():print('working')if __name__ == '__main__':work()

输出:

logging start ...
working
logging end ...

@符号是装饰器的标志,函数work上加一行@work_wrapper的意思是 work = work_wrapper(work)。装饰器可以叠加,我们修改下:

def work_wrapper_a(w):def func(*args, **kwargs):print('a logging start ...')w(*args, **kwargs)print('a logging end ...')return funcdef work_wrapper_b(w):def func(*args, **kwargs):print('b logging start ...')w(*args, **kwargs)print('b logging end ...')return func@work_wrapper_b
@work_wrapper_a
def work():print('working')if __name__ == '__main__':work()

输出

b logging start ...
a logging start ...
working
a logging end ...
b logging end ...

装饰器还可以带参数,如下:

def work_para_wrapper(work_times): def work_wrapper(w):def func(*args, **kwargs):print('logging start ...')[w(*args, **kwargs) for i in range(work_times)]print('logging end ...')return funcreturn work_wrapper@work_para_wrapper(3)
def work():print('working')if __name__ == '__main__':work()

其实跟不带参数的装饰器原理一样,work_para_wrapper(3)会返回一个不带参数装饰器。不但函数可以应用装饰器,类也可以,看下面例子:

def worker_wrapper(cls):class WorkerEnhanced(cls):def learn(self):print('learning new things, {}'.format(self._name))return WorkerEnhanced@worker_wrapper
class Worker:def __init__(self, name):self._name = namedef work(self):print('working')if __name__ == '__main__':w = Worker('Jack')print(type(w))w.learn()

输出

<class '__main__.worker_wrapper.<locals>.WorkerEnhanced'>
learning new things, Jack

另外,利用类的魔术方法 __call__,类也可以作为装饰器。

class WorkerEnhanced:def __init__(self, worker):self._worker = worker()def __call__(self, name):self._worker.Name = namereturn self def learn(self):print('{} is learning new things'.format(self._worker.Name))def work(self):self._worker.work()@WorkerEnhanced
class Worker:def __init__(self, name=None):self._name = name@propertydef Name(self):return self._name@Name.setterdef Name(self, val):self._name = valdef work(self):print('{} is working'.format(self._name))if __name__ == '__main__':w = Worker('Jack')print(type(w))w.work()w.learn()

输出:

<class '__main__.WorkerEnhanced'>
Jack is working
Jack is learning new things

这个例子没什么意义,只是为了说明下怎么使用类来装饰类。最后强调一下,不论是函数装饰器还是类装饰器,原理都是同一个 @ d e c o r a t e t o _ b e _ d e c o r a t e d \frac{@decorate}{to\_be\_decorated} to_be_decorated@decorate ==> t o _ b e _ d e c o r a t e d = d e c o r a t e ( t o _ b e _ d e c o r a t e d ) to\_be\_decorated = decorate(to\_be\_decorated) to_be_decorated=decorate(to_be_decorated)

这篇关于python 设计模式-装饰器模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1119770

相关文章

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文

Python设置Cookie永不超时的详细指南

《Python设置Cookie永不超时的详细指南》Cookie是一种存储在用户浏览器中的小型数据片段,用于记录用户的登录状态、偏好设置等信息,下面小编就来和大家详细讲讲Python如何设置Cookie... 目录一、Cookie的作用与重要性二、Cookie过期的原因三、实现Cookie永不超时的方法(一)

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操