zoukankan      html  css  js  c++  java
  • 野路子码农(5)Python中的装饰器,可能是最通俗的解说

    装饰器这个名词一听就充满了高级感,而且很多情况下确实也不常用。但装饰器有装饰器的好处,至少了解这个对装逼还是颇有益处的。网上有很多关于装饰器的解说,但通常都太过“循序渐进”,有的还会讲一些“闭包”之类的概念,像我这种脑子不太好使的经常就是前读后忘……所以我想自己来写一个非常通俗易懂的解说。

    个人最早真正接触装饰器是在Kaggle上看别人使用numba加速,函数前一行短短的 @jit 让你的代码快到飞起,看起来也很简洁。那究竟装饰器是什么,它又能干嘛呢?

    P1 装饰器的作用

    装饰器的作用是对多种函数执行一个通用操作。重点是多种和通用。举个栗子来说,我写了一个计算执行时长的装饰器,那么我可以把它安在函数A上,也可以把它安在函数B上,甚至安在任何函数上,因为装饰器执行的是一个通用操作,与我把它安在哪个函数上基本无关。注意,这里我们说“多种函数”而不是“任意函数”,因为有些装饰器有特殊用途,并不能在任意函数身上通用。

    P2 装饰器的本体

    我们来看一下装饰器的结构:

    def 装饰器(函数模板):
        骚操作 + 函数模板 (称为wrapper)
        return wrapper

    所以装饰器的本质还是一个函数,这也就是为什么我们说装饰器的作用是执行一个操作,只不过和那些普通平凡的函数都不同的是,装饰器的操作是通用的。

    那么问题又来了,这个”wrapper“又是什么鬼?wrapper说白了就是一系列骚操作和函数模板的集合,装饰器函数返回的就是wrapper,也就是说它返回了函数的return和你所定义的骚操作。

    至于函数模板,它不是任何一个特定的函数,它只是一个泛指。我们可以来看一下wrapper的结构,这里我写的是个最通用的函数模板(通过*args和**kwargs传递任意参数):

    def wrapper(*args, **kwargs):
        前置操作
        func = function(*args, **kwargs)(即函数模板)
        后置操作
        return func

    func = function(*args, **kwargs) 使我们得到了函数执行的结果,无论这个函数是什么函数,而return func将结果返回,连同前后的操作一起作为wrapper扔出去。

    P3 一个例子

    好了,接下来我们来写个例子,一个计算执行时长的装饰器:

    import time
    
    def simple_timeit(function):
        def wrapper(*args, **kwargs):
            start = time.time() # 记录开始时间
            func = function(*args, **kwargs)
            print("用时%.4fs"%(time.time() - start)) # 输出(结束时间-开始时间)
            return func
        return wrapper

    现在我们随便写两个函数,并给它们装上装饰器:

    @simple_timeit
    def sleep(): # 无参数函数
        time.sleep(3)
        return "Get up!!!"
    @simple_timeit
    def break_str(string): # 有参数函数
        txt = [t.upper() for t in string.split(" ")]
        return txt

    执行一下看看结果:

    可以看到对于不同的函数类型,我们的计时器都是通用的。

    总的来说,装饰器能让我们的代码变得简洁,而且能在多个函数上通用。再者由于它是在函数之上额外附加的操作,所以我们只要将装饰器那一行注释掉就能关闭附加功能,而又不影响函数本体的功能,可以说非常方便啦,所以有机会还是值得一用的~

  • 相关阅读:
    python web 2
    python web1(解析url)
    webstrom 今天突然要激活
    数组排序 记录一下
    浏览器添加随机数去除缓存
    vue-cli 安装报错
    vue 初始化项目报错
    深拷贝和浅拷贝
    css3 属性 clip-path
    js数组去重
  • 原文地址:https://www.cnblogs.com/silence-gtx/p/11239556.html
Copyright © 2011-2022 走看看