python 装饰器
之前一直从事php方面的工作,没接触过装饰器,看到@开头的东西觉得非常陌生,无从下手,特意去看了装饰器的用法
帮助理解,纯属个人见解,有错误欢迎指出
1.什么是装饰器
- 装饰器听起来挺高大上,只要理解什么是装饰器即可
- 装饰器本身就是一段代码,一个函数
- 只不过装饰器是个特殊的函数,他的参数接收一个函数,返回值也是一个函数,这点跟普通方法调用区别不大
2.为什么需要装饰器
def add1(x,y): res = x+y return res def sub1(x,y): res = x-y return res
print("add 结果是",add1(10,20)) print("add 结果是",sub1(10,20))
方法功能很简单就是一个加法一个减法,如果这两段代码都需要加上运行时间统计
def add(x,y): before = time() res = x+y after = time() print("耗时%s"%(after-before)) return res def sub(x,y): before = time() res = x-y after = time() print("耗时%s"%(after-before)) return res
你会发现两个方法其实只有运算的地方不一样,其他的全部一模一样,这时候作为懒的我们是不能接受的于是乎就改造变成下面这样
def tt(fuc,x,y): before = time() res = fuc(x,y) after = time() print("耗时%s"%(after-before)) return res print("改造成方法之后add",tt(add(10,20))) print("改造成方法之后sub",tt(add(10,20)))
但是你发现调用起来特别麻烦,方法套方法看起来没逼格,于是继续优化改造
def tt1(fuc): def t2(x,y): before = time() res = fuc(x,y) after = time() print("耗时%s"%(after-before)) return res return t2 add2 = tt1(add1) sub2 = tt1(sub1) print(add2(10,20)) print(sub2(10,20))
这样改成出来的函数直接返回的是一个新的函数,貌似跟上面没什么区别,但是这里返回的是一个新的函数,上面返回的是一个结果集,仅仅是这里有区别,但是这个已经是一个装饰器了,写到这里我看到这样的调用方式我是没办法接受的,但是强大的python给我们提供了语法糖@使用如下
def tt1(fuc): def t2(x,y): before = time() res = fuc(x,y) after = time() print("耗时%s"%(after-before)) return res return t2 @tt1 def add1(x,y): res = x+y return res @tt1 def sub1(x,y): res = x-y return res print(add1(10,20)) print(sub1(10,20))
这样使用代码不仅公用,同时还非常简洁,这就是装饰器
其实一路看下来装饰器的一个@语法糖等价如下
add2 = tt1(add1) sub2 = tt1(sub1) print(add2(10,20)) print(sub2(10,20))
只不过是帮我们做了调用的简化,装饰器本质其实就是调用一个方法来装饰一个方法,返回一个新的方法
再简化点来说就是,需要调用的方法通过装饰器装饰过后给原来的方法添加了一些特有的代码返回新的方法