python装饰器

原则: 封闭开放原则
封闭:对修改是封闭的
开放:对扩展是开放的
装饰器的作用: 在不修改原来函数的情况下添加功能

#假设我们已有函数如下:
def func():
   print('sss')
func()
#我们想加入一个计时的功能
#"错误"实例

#1.如果我们将原函数修改成如下方式
import time
def fun():
   start = time.time()
   print('sss')
   end = time.time()
   print(end - start)
func()
#相当于重构了函数

#2.如果我们单独声明一个计时函数
def timer(f):
   start = time.time()
   f()
   end = time.time()
   print(end - start)
timer(func)
#相当于改变了原来函数的调用方式

#正确方式
#1.
def timer(f):
   def inner():
      start = time.time()
      f()
      end = time.time()
      print(end - start)
   return inner
func = timer(func)
func()

#2.或者使用语法糖相当于func = timer(func)
def timer(f):
   def inner():
      start = time.time()
      f()
      end = time.time()
      print(end - start)
   return inner
@timer
def func():
   print('sss')
func()

#当原函数有返回值时eg:
def func():
   print('sss')
   return 'sss'
ret = func()
print(ret)

#解决方案
def timer(f):
   def inner():
      start = time.time()
      ret = f()
      end = time.time()
      print(end - start)
      return ret
   return inner
@timer
def func():
   print('sss')
   return 'sss'
ret = func()
print(ret)

#当原函数有参数时eg:
def func(a,b,...):#可变参数
#解决方案
def timer(f):
   def inner(*args, **kwargs):
      start = time.time()
      ret = f(*args, **kwargs)
      end = time.time()
      print(end - start)
      return ret
   return inner

#当我们想修改装饰器比如说取消时
#如果对于每一个函数的装饰器都进行修改会很麻烦
#因此我们在装饰器外再嵌套一层
flag = True
#为了避免如果想取消装饰器修时每一个@timer都要重设
def wrapper(flag):
   def timer(f):
      @wraps(f)
      def inner(*args, **kwargs):
         start = time.time()
         ret = f(*args, **kwargs)
         end = time.time()
         print(end - start)
         return ret
      return inner
   return timer

@wrapper(flag)#flag = true; return timer; timer = timer(func)
def func(a,b,c):
   print('sss',a,b,c)
   return 'sss'
ret = func(1,2,"ccc")
print(ret)
print(func.__name__)

你可能感兴趣的:(python学习)