Python 核心技术与实战
景霄
Facebook 资深工程师
114324 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
Python 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

17 | 强大的装饰器

思考题
总结
装饰器用法实例
函数->装饰器
装饰器

该思维导图由 AI 生成,仅供参考

你好,我是景霄。这节课,我们一起来学习装饰器。
装饰器一直以来都是 Python 中很有用、很经典的一个 feature,在工程中的应用也十分广泛,比如日志、缓存等等的任务都会用到。然而,在平常工作生活中,我发现不少人,尤其是初学者,常常因为其相对复杂的表示,对装饰器望而生畏,认为它“too fancy to learn”,实际并不如此。
今天这节课,我会以前面所讲的函数、闭包为切入点,引出装饰器的概念、表达和基本用法,最后,再通过实际工程中的例子,让你再次加深理解。
接下来,让我们进入正文一起学习吧!

函数 -> 装饰器

函数核心回顾

引入装饰器之前,我们首先一起来复习一下,必须掌握的函数的几个核心概念。
第一点,我们要知道,在 Python 中,函数是一等公民(first-class citizen),函数也是对象。我们可以把函数赋予变量,比如下面这段代码:
def func(message):
print('Got a message: {}'.format(message))
send_message = func
send_message('hello world')
# 输出
Got a message: hello world
这个例子中,我们把函数 func 赋予了变量 send_message,这样之后你调用 send_message,就相当于是调用函数 func()。
第二点,我们可以把函数当作参数,传入另一个函数中,比如下面这段代码:
def get_message(message):
return 'Got a message: ' + message
def root_call(func, message):
print(func(message))
root_call(get_message, 'hello world')
# 输出
Got a message: hello world
这个例子中,我们就把函数 get_message 以参数的形式,传入了函数 root_call() 中然后调用它。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Python装饰器是一种强大的工具,通过装饰器函数可以修改原函数的功能而无需实际修改原函数。本文深入介绍了装饰器的概念和基本用法,包括简单装饰器、带参数的装饰器、内置装饰器`@functools.wrap`、类装饰器和装饰器的嵌套用法。此外,作者还结合实际工作中的例子展示了装饰器在身份认证、日志记录、输入合理性检查和缓存等方面的应用。装饰器在实际工作中有着广泛的应用,能够提高程序的可读性和运行效率。通过本文的阅读,读者可以快速了解和掌握Python装饰器的特点和用法,为其在实际工作中的应用提供了丰富的思路和实践案例。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Python 核心技术与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(112)

  • 最新
  • 精选
  • 程序员人生
    我感觉python的装饰器的应用场景有点像AOP的应用场景,把一些常用的业务逻辑分离,提高程序可重用性,降低耦合度,提高开发效率。

    作者回复: 是的,你的理解很正确

    2019-06-17
    6
    86
  • 三水
    请教前辈们或老师一个初入门的问题:在本方前部"函数回顾"中,把函数赋给一个变量时, 第1点:send_message = func 第4点:send_message = func_closure() 我尝试如下会报错: 第1点:send_message = func() 第4点:send_message = func_closure 想知道这是哪一个知识点,谢谢

    作者回复: 第一点: 直接赋值send_message = func()是错误的,因为func()必须接受一个参数,send_message = func('hello world')就正确了,他等同于send_message = func然后send_message('hello world') 第4点:func_closure()是一个闭包,返回的是函数对象。不能直接用send_message = func_closure,然后send_message('hello world')调用,必须是send_message = func_closure(),然后再send_message('hello world'),这样才能把参数'hello world'正确传给内部函数

    2019-06-17
    42
  • 吴星
    请教下,为什么count那儿是单例模式吗?为什么二次执行会加1?

    作者回复: 因为num_calls这个变量是类变量,不是具体的实例变量,二次执行相当于调用了函数__call__两次,因此变量num_calls会变为2

    2019-06-17
    12
    11
  • 被炸的油条
    工作当中,如果是二次开发,在原来的需求基础之上做优化,原逻辑不需要修改的情况下,只需增加新的业务场景的时候,感觉用装饰器挺好的。不动原来的逻辑,增加程序的健壮性。

    作者回复: 正解

    2019-09-22
    9
  • farFlight
    请问一下,lru cache不是应该删除最久没有访问的内容吗。

    作者回复: LRU cache is to remove the least recently used data when the cache is full。翻译过来可能有点问题,意思就是删除最久没有访问的,我还是直接保留英文解释吧。

    2019-06-17
    4
    8
  • 🇨🇳
    1、总结中,倒数第二行发现错别字(程序)不是程度。 2、类装饰器在实际中有哪些应用场景呢

    作者回复: 欢迎指正错别字。类装饰器的用途和函数装饰器差不多,比如文中所讲的机器学习中需要对输入进行合理性检查,他也常常可以写成类装饰器的形式,进行调用。写成类的话,优点是程序的分解度更加高,具体用类装饰器和函数装饰器,视情况而定,二者本质是一样的

    2019-06-17
    2
    7
  • geraltlaush
    我之前开发过微服务脚手架,跟装饰器模式很像,就是rpc调用之前,把限流,上报,统计耗时统计在前面,每个功能还可以自由选择执行的时机,跟业务功能分离,开发关注于业务研发就行了

    作者回复: 说的很好

    2019-11-07
    6
  • enjoylearning
    还有类装饰器,又长见识了,最近正愁参数校验放哪里,参照本文终于开窍了

    作者回复: 很高兴看到你有所收获

    2019-06-17
    6
  • 向南
    装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对象。 它经常用于有特定需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,装饰器是解决这类问题的绝佳设计。 有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。 装饰器并没有修改原函数,或者说装饰器并没有修改原函数的功能,而为其新增其他功能。

    作者回复: 对

    2020-03-08
    5
  • Hoo-Ah
    目前工作中使用的是tornado框架,里面依赖tornado.gen.coroutine这个装饰器用来将被装饰的函数变为协程,这样就可以将代码的执行变为异步非阻塞,提高程序的并发量。

    作者回复: 嗯嗯

    2019-06-17
    5
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部