装饰器的画图直观理解

装饰器怎么用

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

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

直观理解

函数就是不同形状的盒子

请添加图片描述

有一个小机器人,你给小机器人一个盒子,这个小机器人会加工这个盒子,怎么加工的呢?

调皮的小机器人新造了一个和你这个盒子的形状(左右窟窿数量一样)的新盒子,然后把你给他的盒子放到新盒子里,(可能在这中间还会多塞进去一些新东西)装好之后再把这个新盒子给你,并说:“加工好了啦~”


翻译:

你有一个装饰器,你给装饰器一个函数,这个装饰器会加工这个函数,怎么加工的呢?

调皮的装饰器新造了一个和你这个函数的形状(参数数量和返回值类型一样)的新空函数,然后把你给他的函数放到新函数里,(可能在这中间还会加一些新功能)装好之后再把这个新函数给你,并说:“装饰好了啦~”

请添加图片描述

实现得一些现成的装饰器

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')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值