为什么说想到Python中的装饰器是天才

只需一个@符号就能分析、测试和重复使用你的代码


带着魔杖的仙女在Python代码中飞舞

软件中有没有什么是神奇的小魔法? 有,装饰器却非常接近!

如果说有一件事使Python难以置信地成功,那就是它的可读性。其他一切都取决于此:如果代码不可读,就很难维护。那么它也对初学者不友好--一个被不可读的代码弄得晕头转向的新手,有一天也不会尝试写自己的代码。

在装饰器出现之前,Python 已经是可读的,并且对初学者友好。但随着语言开始被用于越来越多的事情,Python 开发者感到需要越来越多的功能,同时又不至于杂乱无章,使代码无法阅读。

装饰器是一个完美实现功能的典型例子。它确实需要花点时间来理解,但这是值得的。当你开始使用它们时,你会注意到它们不会使事情过度复杂化,并使你的代码变得整洁而时髦。

在其他事情之前:高阶函数

简而言之,装饰器是处理高阶函数的一种整洁的方式。所以让我们先来看看这些

返回函数的函数 假设你有一个函数,greet() - 它向你传递的任何对象致意

假设你有另一个函数,simon() - 它在适当的地方插入 "Simon"

我们怎样才能把这两个函数结合起来呢? 在你看下面的内容之前先想一想。

def greet(name):    return f"Hello, {name}!"

def simon(func):    return func("Simon")

simon(greet)The output is 'Hello, Simon!'.

输出是 "你好,西蒙!"

希望这对你了解函数返回一个函数有意义!

当然,我们可以直接调用greet("Simon")。然而,重点是我们可能想把 "Simon "放到许多不同的函数中。如果我们不使用 "Simon",而是使用更复杂的东西,我们可以通过把它打包到simon()这样的函数中来节省大量的代码行。

函数中的函数

我们也可以在其他函数中定义函数。这一点很重要,因为装饰器也会这样做。如果没有装饰器,它看起来像这样。

下面的函数是接受参数 gpa 成绩,如果是‘yes’或大于‘90’分则调用函数 congrats() 否则,调用函数 encourage()

#练习修改

def respect(gpa):    def congrats():        return "Congrats, Your gpa is excellent!"

    def encourage():        return "You're have change to try again"

    if gpa == "yes":         return congrats()    else:         return encourage()

gpa = '91' #'python'gpa = "no"

print(f"{gpa},{respect(gpa)}")

#output:no,You're have change to try again

另外找时间讲一个意外:

print(gpa > '90')# 注意字符串的比较结果意外吧?

函数 respect() 返回一个函数; respect("yes") 返回祝贺函数, respect("brother") (或其他参数代替 "brother")返回鼓励函数。

要调用这些函数,请输入 respect("yes") 和 respect("brother"),就像普通函数一样。

明白了吗?那么你就可以为装饰者做好准备了!

代码是美丽的书呆子

在电脑屏幕前显示<code/is/beautiful>的女人

Python装饰器的ABC 带有@符号的函数 让我们尝试一下前面两个概念的组合:一个函数接收另一个函数,并定义一个函数。听起来很匪夷所思?考虑一下这个。

def startstop(func):    def wrapper():        print("开始...")        func()        print("完成了!")    返回包装器def roll():    print("在地上打滚,笑死人了 XD")

roll()#OUPUT:

Starting...Rolling on the floor laughing XDFinished!

最后一行确保我们不再需要调用

startstop(roll)()

roll()就足够了。你知道这个调用的输出是什么吗?如果你不确定的话,就自己试试吧!

现在,作为一个非常好的替代方案,我们可以在定义startstop()之后直接插入这个。

@startstopdef roll():    print("在地板上笑着打滚 XD")

这样做是一样的,但是在开始时就把roll()和startstop()粘在一起了。

增加了灵活性

为什么会有这样的作用?这不是要消耗和以前一模一样多的代码行吗?

在这种情况下,是的。但是一旦你要处理稍微复杂的东西,它就会变得非常有用。这一次,你可以把所有的装饰器,即上面的def startstop()部分移到它自己的模块里。

也就是说,你把它们写进一个叫做decorators.py的文件,然后在你的主文件中写上类似这样的内容。

from decorators import startstop@startstopdef roll():    print("在地上打滚,笑死我了XD")

原则上,你可以不使用

decorators.py

来做这个。但这种方式使生活更简单,因为你不必再处理嵌套函数和无休止的括号计算了。

你也可以同时再嵌套其他装饰器。譬如计算函数执行时间的 exectime

from decorators import startstop, exectime@exectime@startstopdef roll():    print("在地上打滚,笑死人了 XD")

注意,我们还没有定义exectime(),但你会在看到它。它是一个可以测量Python中一个过程所需时间的函数。这样的嵌套相当于这样的一行。

导入time时间库

import time

# 用来计算持续时间的装饰器# 被任何函数占用的时间。

def exectime(func):    # 在inner1内添加参数。    # 如果函数需要任何参数。    # 可以像这样添加。    def inner1(*args, **kwargs):        # 储存函数执行前的时间        begin = time.time()

        func(*args, **kwargs)

        # 储存函数执行后的时间        end = time.time()        print("Total time taken in : " , func.__name__, end - begin)

    return inner1

现在就可以正常运行了

# 调用上面已经定义excetime函数!from decoratorsRoll import startstop, exectime  @exectime@startstopdef roll():    time.sleep(3)    print("Rolling on the floor laughing XD")roll()

roll = exectime(startstop(roll))print(roll())

Starting...Rolling on the floor laughing XDFinished!Total time taken in :  wrapper 3.0007543563842773

括号内的计数开始了! 想象一下,你有五六个这样的函数相互嵌套在一起。装饰器的符号不是比这种嵌套的混乱更容易阅读吗?

你甚至可以在接受参数的函数上使用装饰器。现在想象一下,在上面那行中有几个参数,你的混乱就会完成。装饰器让它变得整齐划一。

最后,你甚至可以向你的装饰器添加参数--比如@mydecorator(argument)。是的,你可以不用装饰器来做这一切。但是,我祝愿你在三周后重读你的无装饰器的代码时,会有很多乐趣......


女人站在桌子上,上面放着电脑、浓缩咖啡杯和花瓶

装饰者使一切变得更容易

应用:装饰者切入的地方 现在,我希望能说服你,装饰器使你的生活轻松三倍,让我们看看一些经典的例子,在这些例子中,装饰器基本上是不可缺少的。

测量执行时间 上面的写法稍作变化:time.perf_counter()

假设我们有一个叫做waste time()的函数,我们想知道它需要多长时间执行完函数。那么,就用一个装饰器:

import timedef measuretime(func):    def wrapper():        starttime = time.perf_counter()        func()        endtime = time.perf_counter()        print(f"Time needed: {endtime - starttime} seconds")    return wrapper

@measuretimedef wastetime():    sum([i**2 for i in range(1000000)])wastetime()

十几行代码,我们就完成了! 另外,你可以在任意多的函数上使用 measuretime()

减缓代码速度

有时你不想立即执行代码,而是要等待一段时间。这时,减速装饰器就派上用场了。

import timedef sleep(func):    def wrapper():        time.sleep(300)        return func()    return wrapper@sleepdef wakeup():    print("Get up! Your break is over.")wakeup()

调用wakeup()使得你可以休息5分钟,之后你的控制台会提醒你回去工作。

测试和调试

假设你有一大堆不同的函数,你在不同的阶段调用,而你对什么时候被调用失去了概览。通过对每个函数定义的简单装饰器,你可以使其更加清晰。就像这样。

def debug(func):    def wrapper():        print(f"Calling {func.__name__}")    return wrapper@debugdef scare():    print("Boo!")scare()

这里有一个更详细的例子。不过要注意的是,要理解这个例子,你必须检查如何用参数来装饰函数。不过,这还是值得一读的!

重用代码

这一点不言而喻。如果你已经定义了一个函数decorator(),你就可以在你的代码中到处撒上@decorator。说实话,我认为没有比这更简单的了。

处理登录

如果你有一些功能只有在用户登录后才能访问,使用装饰器也是相当容易的。我会让你参考完整的例子,但原理很简单:首先你定义一个类似login_required()的函数。在任何需要登录的函数定义之前,你弹出@login_required

我想说,这让调用变得很简单!

语法糖--为什么Python是如此的甜蜜

Python有一个很大的诱惑力:它是如此容易理解,即使你不是一个受过训练的计算机科学家,而只是想让事情运转,帮你快速上手解决问题!

如果C++是一个橙子,那么Python就是一个菠萝:营养相似,但甜度要高三倍。装饰器只是其中的一个因素。

但我希望你已经明白了为什么它是如此大的一个甜味因素。合成糖为你的生活增添一些乐趣!这就是合成糖。没有健康风险,除了让你的眼睛粘在屏幕上。

我祝愿你有很多甜蜜的代码!

本文由 mdnice 多平台发布

为什么说想到Python中的装饰器是天才相关推荐

  1. python装饰器原理-python 中的装饰器及其原理

    装饰器模式 此前的文章中我们介绍过装饰器模式: 装饰器模式中具体的 Decorator 实现类通过将对组建的请求转发给被装饰的对象,并在转发前后执行一些额外的动作来修改原有的部分行为,实现增强 Com ...

  2. python类装饰器详解-python 中的装饰器详解

    装饰器 闭包 闭包简单的来说就是一个函数,在该函数内部再定义一个函数,并且这个内部函数用到了外部变量(即是外部函数的参数),最终这个函数返回内部函数的引用,这就是闭包. def decorator(p ...

  3. python中的装饰器decorator

    python中的装饰器 装饰器是为了解决以下描述的问题而产生的方法 我们在已有的函数代码的基础上,想要动态的为这个函数增加功能而又不改变原函数的代码 例如有三个函数: def f1(x):return ...

  4. python编写装饰器_写python中的装饰器

    python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) 1 de ...

  5. python中的装饰器(基础装饰器)

    文章目录 一 前置知识-高阶函数,闭包 1. 高阶函数 2. 闭包 二 函数装饰器 1. 什么是装饰器(原理)? 2. 装饰器的实现 3. 何时执行装饰器 4. wraps方法 三 类装饰器 一 前置 ...

  6. [转载]理解PYTHON中的装饰器

    [翻译]理解PYTHON中的装饰器 来源stackoverflow上的问题 链接 python的函数是对象 要理解装饰器,首先,你必须明白,在python中,函数是对象. 这很重要. 简单例子来理解为 ...

  7. python中的装饰器有哪些-python 装饰器以及开发中常用的例子

    有时候我们想为多个函数,同意添加某一种功能,比如及时统计,记录日志,缓存运算结果等等,而又不想改变函数代码 那就定义装饰器函数,用它来生成一个在原函数基础添加了新功能的函数,代替原函数 参考金角大王的 ...

  8. python中的装饰器怎么运行_Python 装饰器入门(上)

    翻译前想说的话: 这是一篇介绍python装饰器的文章,对比之前看到的类似介绍装饰器的文章,个人认为无人可出其右,文章由浅到深,由函数介绍到装饰器的高级应用,每个介绍必有例子说明.文章太长,看完原文后 ...

  9. Python中的装饰器是什么?装饰器是如何工作的?

    Python很早就引入了装饰器--在PEP-318中,作为一种简化函数和方法定义方式的机制,这些函数和方法在初始定义之后必须进行修改. 这样做的最初动机之一是,使用classmethod和static ...

最新文章

  1. hash 值重复_程序员:判断对象是否重复,不重写equals和hashcode不行吗?
  2. 厦门大学计算机专业录取分数线2019,厦门大学2019年本科生录取分数线
  3. 深入浅出 MyBatis 的一级、二级缓存机制
  4. 世界坐标系到观察坐标系的变换步骤_《3D数学基础》提炼总结(九)矩阵和线性变换...
  5. php常用的十个代码片段,转载
  6. 计算机职称excel2007,职称计算机Excel2007中文电子表格考试大纲
  7. php xlsx里插入图片_常见的 PHP 面试题和答案分享
  8. 曝苹果iPhone 13将于8月开始大批量产,恶劣天气不会造成影响
  9. 能源路由器入门必读:面向能源互联网的架构和功能
  10. PeopleCert认证证书核验真伪(含ITIL、PRINCE2、DevOps、Scrum……等证书)
  11. html5 |移动 游戏 毕业设计,移动平台下基于HTML5的教育游戏研究与设计
  12. 面试官:请实现单行文本居中,多行文本左对齐?
  13. EasyExcel导出Excel设置单元格文本格式(亲测有效)
  14. 【点云处理技术之PCL】点云配准算法之NDT
  15. Python AutoCAD 修改
  16. #Eclipse IDE for Java EE Developers 的下载及初步使用
  17. 安装dplyr报错之rlang’ 0.4.5,但需要的是>= 0.4.10
  18. 微软谷歌苹果耳机大战 智能竞赛的又一战场
  19. 宁波银行金融科技面试
  20. 【TS TSP】基于matlab禁忌搜索求解旅行商问题【含Matlab源码 447期】

热门文章

  1. 处理表中id字段中,序号顺序不连贯
  2. 易保全亮相中国独角兽商机大会(长沙站),区块链应用助力企业家轻松布局
  3. 361页13万字“智慧公安”系统工程设计方案
  4. python实现qq登录腾讯视频_Python爬取腾讯视频评论的思路详解
  5. 格式化字符串php代码,格式化字符串
  6. python如何读取文件内容求和_python读文件统计次数和求和怎么写?
  7. Machine Learning --- zero-mean whiten(data preprocessing)
  8. springboot高考志愿选择系统 -计算机毕设 附源码68335
  9. Linux日志服务器_ELK搭建
  10. 自学Python可以吗?怎样从零基础到大师?我写这篇文章告诉你