引言
在软件开发中,我们经常会遇到一些横切关注点(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 + y
def xiaowang_add():
print("xiaowang 666")
return laowang_add
add = xiaowang_add()
print(add(1, 2))
那么这样可以在不修改老王的代码基础上做了一次增强,那么如果我想在所有的方法上前去做一次日志输出,那么上述的做法就不适用了,不可能以后新增一个函数都去改一下闭包函数。此时就需要装饰器,也叫切面编程。简单来讲,我把一个代表函数的变量传进闭包函数,然后这个闭包函数就可以自适应传进去的函数,自动调用它,不用每次新增函数都去修改闭包,只用调用一次闭包函数即可。此时装饰器模式就闪亮登场了。
我们只需要增加一个方法
import time
import functools
def 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 result
return 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__输出就是调用的方法名,没有小王代替。
标签:end,python,start,add,切面,time,装饰,def From: https://www.cnblogs.com/lyuSky/p/18406510