欢迎光临散文网 会员登陆 & 注册

【python技巧009】画图直观展示装饰器的本质, 来N层装饰器都不怕了!

2022-05-11 22:57 作者:阿-岳同学  | 我要投稿

装饰器怎么用

函数理解成:“带窟窿的纸盒子盒子”
装饰器加工过程 涂鸦方式 直观展示
直观理解装饰器
会写装饰器
展示一些种装饰器实例:
 添加日志、修改参数位置
 保险处理、统计函数执行次数
 延迟执行函数、多次执行函数

多层装饰器
多层装饰的顺序问题
带参数的装饰器
类装饰器

实现得一些现成的装饰器

def logger(oldFunc):
  """夹层装饰器,给函数调用前后加两个打印突出显示"""
  def newFunc():
    print("~~~~~~~~~~~")
    oldFunc()
    print("~~~~~~~~~~~")
   ...

  return newFunc


def logger2(oldFunc):
  """夹层装饰器,只给头顶增加一个打印"""
  def newFunc():
    print("+++++++++++")
    oldFunc()
   ...

  return newFunc


def runDouble(oldFunc):
  """给一个函数装饰,装饰后这个函数就能运行两次了"""
  def newFunc():
    oldFunc()
    oldFunc()

  return newFunc


def counter(oldFunc):
  """记录一个函数打印了多少次"""
  count = 0

  def newFunc():
    nonlocal count
    count += 1
    oldFunc()
    print(f"这个函数{oldFunc.__name__}运行了{count}次")
   ...

  return newFunc


def shield(oldFunc):
  """防护盾装饰器,让一个函数在运行中不会发生错误导致程序终止"""
  def newFunc():
    try:
      oldFunc()
    except Exception as e:
      print(f"函数{oldFunc.__name__}出错了", oldFunc, e)

  return newFunc()


from functools import lru_cache


@lru_cache(None)
def func():
  print("hello")


@lru_cache()
def func2():
 ...


class Check(object):
  """类装饰器"""
  def __init__(self, fn):
    """
   传入的是被装饰的原的函数
   """
    self.__fn = fn

  def __call__(self, *args, **kwargs): # 实现__call__方法,表示对象是一个可调用对象,可以像调用函数一样进行调用
    print("登录") # 在这之前可以写登录代码
    self.__fn()

带参数的装饰器

写法是套了三层def,中间那层def是原来的装饰器的那个(小机器人)。

import time

"""
带参数的选择器
timer() 加小括号调用结束之后,本身会变成一个不带参数的装饰器(小机器人)
然后这个装饰器再对函数进行装饰
"""
def timer(time_type):
  
  print(time_type)
  if time_type == "min":
    def robot(func):
      print("func的名字是:", func.__name__)

      def inner(*args, **kwargs):
        start = time.time()
        func(*args, **kwargs)
        end = time.time()
        res = end - start
        print('时间结果是:', res)

      return inner
  else:
    def robot(func):
      print("func的名字是:", func.__name__)

      def inner(*args, **kwargs):
        start = time.time()
        func(*args, **kwargs)
        end = time.time()
        res = end - start
        print('时间结果是:', res)

      return inner
  return robot


@timer('min')
def foo(a, b, c):
  print('in foo', a, b, c)


foo('a', 'bb', 'ccc')


【python技巧009】画图直观展示装饰器的本质, 来N层装饰器都不怕了!的评论 (共 条)

分享到微博请遵守国家法律