python装饰器模式实现切面功能

news/2025/1/15 13:59:36/文章来源:https://www.cnblogs.com/lyuSky/p/18406510

引言

在软件开发中,我们经常会遇到一些横切关注点(cross-cutting concerns),如日志记录、事务管理、安全性检查等,这些关注点通常会跨越多个模块。传统的编程方式会导致代码的重复和分散,难以维护。面向切面编程(AOP)是一种编程范式,它通过提供一种新的方式来模块化横切关注点,从而提高代码的模块性和可维护性。

什么是切面(AOP):

AOP是一种编程思想,它允许开发者将横切关注点从业务逻辑中分离出来,形成所谓的“切面”(Aspect)。切面可以定义在程序执行的特定点(如方法调用前后)插入额外的逻辑,这些点被称为“连接点”(Join Points)。AOP的主要目标是提高模块化,使得业务逻辑更加清晰,同时减少代码的重复。

在Java中可以使用动态代理,Spring Aop(实际上还是动态代理),AspectJ等手段去实现切面功能。那么在Python 怎么去实现切面呢?就拿一个最简单的例子来说,打印每一个方法的耗时时长。

常规写法

import time
def method1():start = time.time()# 业务方法end = time.time()print(f"耗时:{end-start}",)def method2():start = time.time()# 业务方法end = time.time()print(f"耗时:{end-start}",)def method3():start = time.time()# 业务方法end = time.time()print(f"耗时:{end-start}",)

可以看到随着业务的增加,会增加很多的这样的代码,这样的代码重复率很高,不满足开闭原则,那么可以考虑将这些非业务方法抽取出来做一个公共方法,然后去调用它,那么怎么去实现呢?
那就不得不说python中的装饰器模式了。

举一个栗子,老王写了一个加法函数

def laowang_add(x:int,y:int):return x+y

当时小王呢,想在求和之前增加一个日志,但是又不想在老王的代码基础上改,那要怎么做呢?可以这样

def laowang_add(x: int, y: int):return x + ydef xiaowang_add():print("xiaowang  666")return laowang_addadd = xiaowang_add()
print(add(1, 2))

那么这样可以在不修改老王的代码基础上做了一次增强,那么如果我想在所有的方法上前去做一次日志输出,那么上述的做法就不适用了,不可能以后新增一个函数都去改一下闭包函数。此时就需要装饰器,也叫切面编程。简单来讲,我把一个代表函数的变量传进闭包函数,然后这个闭包函数就可以自适应传进去的函数,自动调用它,不用每次新增函数都去修改闭包,只用调用一次闭包函数即可。
此时装饰器模式就闪亮登场了。

我们只需要增加一个方法

import time
import functoolsdef log_decoration(func):@functools.wraps(func)def log(*args, **kwargs):print(f"entry {func.__name__} method")start = time.time()result = func(*args, **kwargs)end = time.time()print(f"end {func.__name__} method cost {end - start}")return resultreturn log@log_decoration
def laowang_add(x: int, y: int):return x + y

输出

entry laowang_add method
end laowang_add method cost 0.0
3

可以看到老王虽然只实现了业务逻辑,但是增加了日志输出,就像该方法被拦截切断了一样,然后自动增加了日志输出,这就是切面,不修改业务方法,只增强业务方法。可以看到
func.__name__输出就是调用的方法名,没有小王代替。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/794989.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Salesforce职业规划:原厂,甲方,乙方,从业者应该如何选择?

Salesforce生态系统蓬勃发展,对不同角色的需求量不断增加。需求方包括使用Salesforce的最终用户(甲方)、实施Salesforce的咨询公司、为Salesforce创建应用程序的AppExchange公司(或ISV),当然还有Salesforce原厂。 Salesforce最终用户(甲方) 2020年,Salesforce的客户数…

3SRB5016-ASEMI三相整流桥3SRB5016

3SRB5016-ASEMI三相整流桥3SRB5016编辑:ll 3SRB5016-ASEMI三相整流桥3SRB5016 型号:3SRB5016 品牌:ASEMI 封装:3SRB-5 批号:2024+ 现货:50000+ 最大重复峰值反向电压:1600V 最大正向平均整流电流(Vdss):50A 功率(Pd):大功率 芯片个数:5 引脚数量:5 安装方式:直插 类…

34-样式迁移

类似于加了一层滤镜基于CNN的样式迁移:如下对于合成图片X,我们希望它的内容和输入的内容图片,放入同一个CNN,在某一个卷积层上,输出的与内容有关的特征能够匹配 同时,,对于样式图片,我们希望合成图片X,和样式图片放入同一个CNN,在某一个卷积层上,输出的与样式有关的…

STM32-ADC外设

1.通道 .规则通道 .注入通道 2.规则序列寄存器 配置通道的采样顺序 3.ADC周期4.ADC转换方式 *单次转换:adc每次只采集某个通道的一个点,如果需要再次采集,就需要重新使能。 *连续转换:adc采集某个通道一个点,转换完成后,再采集第二点。依次类推 4.扫描模式 *单次扫描模式…

SignalR跨域问题解决

本文来自博客园,作者:WantRemake,转载请注明原文链接:https://www.cnblogs.com/SmallChen/p/18406437

字符串类

常用类String基础知识String类的特性String类是一个final类,不能被继承 String类底层是一个final修饰的字符数组,表示不可变的字符序列(final char value[ ]) String的不可变性:当String值改变时,会在常量池中创建新的字符串字符串-创建字面量方式创建 String s1="a…

AI答案之书解来为你解决难题

本文由 ChatMoney团队出品介绍说明 “答案之书智能体”是您贴心的智慧伙伴,随时准备为您解答生活中的种种困惑。无论您在工作中遭遇瓶颈,还是在情感世界里迷失方向,亦或是对个人成长感到迷茫,它都能倾听您的心声,并给予准确且富有启发的回应。 它并非简单地给出答案,而是…

解锁生活密码,AI答案之书解决复杂难题

本文由 ChatMoney团队出品介绍说明 “答案之书智能体”是您贴心的智慧伙伴,随时准备为您解答生活中的种种困惑。无论您在工作中遭遇瓶颈,还是在情感世界里迷失方向,亦或是对个人成长感到迷茫,它都能倾听您的心声,并给予准确且富有启发的回应。 它并非简单地给出答案,而是…

STM32F7外设FMC控制LCD显示屏

STM32F7外设FMC控制LCD显示屏, 显示屏的点阵LCD控制器(Dot Matrix LCD Controller/Driver)是ST7066U。 配置 在CubeMX中选择图 1 根据实际情况选择,Bank几,LCD片选引脚。图 2 FMC原理 对于FMC如何控制LCD,我的理解: FMC能自动发送数据读写RAM,通过FMC读写LCD的显存就可以…

推荐一款好用的golang修复无效json的库:JSONRepair

简单来说,就是可以将错误格式(非标准)的json修正,如下图所示: 我的json明显不是标准的json格式,是不能被解析的: 但是JSONRepair库也能修复。github地址:https://github.com/kaptinlin/jsonrepair 使用也非常简单: 1、安装:go get github.com/kaptinlin/jsonrepair2、…

全志T507-H国产平台Ubuntu系统正式发布,让您的应用开发更便捷!

为了满足广大工业用户的需求,创龙科技针对全志T507-H工业平台进行了Ubuntu系统适配,开发环境如下: Ubuntu:Ubuntu18.04.4 U-Boot:U-Boot-2018.05 Kernel:Linux-4.9.170、Linux-RT-4.9.170 LinuxSDK:LinuxSDK-[版本号].tar.gz (基于全志官方V2.0_20220618)全志T507-H国…