装饰器

什么是装饰器:

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能

语法:@

1.装饰器的原型

def printInfo():
   print("我是一个普通的函数")

printInfo()

如何在不允许修改printInfo函数的前提下,在执行printInfo函数前进行权限校验;执行后进行日志记录。

def check(func):

   def checkAndLog():
      print("函数执行前:权限校验")
      func()
      print("函数执行后:日志记录")
   return checkAndLog       #返回内部函数

def printInfo():
   print("我是一个普通的函数")

# printInfo()

newFunc = check(printInfo)
newFunc()        #执行内部函数

2.装饰器的定义和调用

#装饰器函数定义
def check(func):

   def checkAndLog():
      print("函数执行前:权限校验")
      func()
      print("函数执行后:日志记录")
   return checkAndLog       #返回内部函数(包装过的函数)
@check    #定义装饰器修饰的位置,用来修饰谁,相当于check(printInfo)
def printInfo():
   print("我是一个普通的函数")

printInfo()#执行函数前,会先执行装饰器

3.装饰器的嵌套

def zs1(func):
   def f():
      print("我是装饰器1,我来啦")
      func()
      print("我是装饰器1,我走啦")
   return f
def zs2(func):
   def f():
      print("我是装饰器2,我来啦")
      func()
      print("我是装饰器2,我走啦")
   return f

@zs2
@zs1      #自下而上逐步修饰,zs2会把zs1返回的函数进行修饰,一层套一层
def printInfo():
   print("我是一个普通的函数")

printInfo()

4.带参数的装饰器

如果原函数带有参数,那么返回的包装后的新函数也要带有参数,且参数需要一一对应

def tool(func):
   def log(name,pwd):       #如果log不传入参数,func将接收不到参数
      print(f"日志记录【{name}:{pwd}】")
      func(name,pwd)
   return log       #返回包装过的函数
@tool
def login(name,pwd):
   print(f"用户名:{name},密码:{pwd}")

login("admin",123456)

5.带返回值的装饰器

返回值和原函数定义时相同

def tool(func):
   def log(name,pwd):       #如果log不传入参数,func将接收不到参数
      print(f"日志记录【{name}:{pwd}】")
      state = func(name,pwd)
      return state
   return log       #返回包装过的函数
@tool
def login(name,pwd):
   print(f"用户名:{name},密码:{pwd}")
   if name == "admin" and pwd == 123456:
      return "登陆成功"
   return "登录失败"


res = login("admin",123456)
print(res)

6.定义通用的装饰器

增加装饰器的适用性

def tool(func):
   def log(*args,**kwargs):			#通过使用可变参数来增加装饰器的适用性
      print("日志记录前。。。")
      state = func(*args,**kwargs)
      print("日志记录后。。。")
      return state
   return log       #返回包装过的函数

@tool
def test():
   print("我是一个测试函数")

@tool
def login(name,pwd):
   print(f"用户名:{name},密码:{pwd}")
   if name == "admin" and pwd == 123456:
      return "登陆成功"
   return "登录失败"


res = login("admin",123456)
print(res)
test()
posted on 2020-12-01 15:19  凌落宸  阅读(59)  评论(0编辑  收藏  举报