装饰器——我也不太懂是什么东西 你们自己看

22人参与 |分类: 基本知识|时间: 2020年07月30日

  一、什么是装饰器?

  器 就是工具 可以用函数定义

  装饰 为其他事物添加功能

  合到一起可以理解成是定义一个函数来装饰其他函数。给其他函数添加额外的功能。

  装饰器 的使用满足开放封闭原则

  即对于代码功能的拓展是开放的

  对于修改源代码是封闭的

  合到一起就是不能改函数的调用方式,和原函数的代码,但是要增加原函数的功能。

  二、装饰器怎么定义?

  from functools import wraps

  def outter(func):

  @wraps(func)   # 将wrapper函数伪装成func函数的工具,除了返回值,参数以外,包括func的内置属性__name__,__file__等等都伪装成一样的。

  def wrapper(*args,**kwargs):  # 确保wrapper的参数,返回值,调用方式都跟func一模一样,但是可以增加一些功能

  # 功能可以增加在这里

  res = func(*args,**kwargs)

  return res

  return wrapper

  ==============================>  下面是函数的调用阶段啦

  func = outter(func)  # 返回值就是wrapper函数的内存地址,之后再加上括号就可以实现在不改变func函数的代用方式,和代码的情况下,实现对于func功能的增加。这就是无参装饰器的模板啦!

  python给我们提供了语法糖,准许我们将func = outter(func) 这样的语句,简写成

  @outter  # 在被装饰的函数上面声明装饰器即可实现为函数加上功能,可以制作一些认证装饰器,时间装饰器,等等

  def func(*args,**kwargs):

  pass

  ==================================================》 下面是有参装饰器啦~

  from functools import wraps

  def code(x):

  def outter(func):

  @wraps(func)

  def wrapper(*args,**kwargs):  # 确保wrapper的参数,返回值,调用方式都跟func一模一样,但是可以增加一些功能

  # 功能可以增加在这里

  res = func(*args,**kwargs)

  return res

  return wrapper

  return outter

  ==============================>  下面是函数的调用阶段啦

  受语法糖的限制,我们不能再outter函数中在增加参数了,但是如果确实还有需要传进来的变量参数呢,我们可以通过再嵌套一层的方法给函数传参。

  outter = code(x)

  无参装饰器时语法糖是 将 func = outter(func)  ---> 简化成 ---> @outter

  现在outter 就是 code(x) -----------------------------------------------> @code(x)  这就是有参的装饰器啦~,这里传X只是一个例子,其实可以传不限的参数。

  三、如何使用装饰器

  1.定义一个计算函数运行时间的装饰器

  from functools import wraps

  import time

  def timmer(func):

  @wraps(func)

  def wrapper(*args,**kwargs):  # 确保wrapper的参数,返回值,调用方式都跟func一模一样,但是可以增加一些功能

  # 功能可以增加在这里

  start = time.time

  res = func(*args,**kwargs)

  end = time.time

  print(f‘执行函数用时start-end秒’)

  return res

  return wrapper

  1.定义一个认证功能的装饰器

  from functools import wraps

  def auth(func):

  @wraps(func)

  def wrapper(*args,**kwargs):  # 确保wrapper的参数,返回值,调用方式都跟func一模一样,但是可以增加一些功能

  # 功能可以增加在这里

  user_name = input('用户名>>>:‘)

  psd = input('密码>>>:')

  # 从文件查找用户名和密码认证

  f = open('a.txt')

  for line in f:

  if user_name.split().lower() in line.lower and psd in line:

  res = func(*args,**kwargs)

  return res

  else:

  print('登录失败')

  return wrapper