Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >python装饰器和语法糖

python装饰器和语法糖

作者头像
烤粽子
发布于 2021-07-07 10:20:08
发布于 2021-07-07 10:20:08
84200
代码可运行
举报
运行总次数:0
代码可运行

装饰器在大工程中比较常见,那么如何理解装饰器呢?打个比方,假如你建好了一栋大房子,建好后还想加一些功能,这个时候房子的主体结构是不能动了,只好在现有房子的基础上做一些装饰/装修。这些装饰在不影响/不修改原来房子功能的基础上,增加了美观等功能。

装饰器是可调用的对象,其参数是另一个函数(被装饰的函数)。 装 饰器可能会处理被装饰的函数,然后把它返回,或者将其替换成另一个 函数或可调用对象。[2]

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@decorate
def target():
    print('running target()')

def target():
    print('running target()')
target = decorate(target)

上述两种写法的代码效果一样。 上面出现的@符号就是装饰器的语法糖,它放在函数开始定义的地方,这样就可以省略最后一步再次赋值的操作。 注意:Python 中的函数和 Java、C++不太一样,Python 中的函数可以像普通变量一样当做参数传递给另外一个函数,例子如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def foo():
    print("foo")

def bar(func):
    func()

foo()
bar(foo)
bar

函数调用:

  • 不带括号时,调用的是这个函数本身 ,是整个函数体,是一个函数对象,不须等该函数执行完成
  • 带括号(参数或者无参),调用的是函数的执行结果,须等该函数执行完成的结果
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 装饰器通常把函数替换成另一个函数
def deco(func):
    def inner():
        print('running inner()')
    return inner # deco 返回 inner 函数对象

@deco
def target(): # 使用 deco 装饰 target。
    print('running target()')

# target = deco(target) # 有了语法糖这句可以省略  相当于 target = wrapper
target() # 调用被装饰的 target 其实会运行 inner。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
running target()
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
target # 审查对象,发现 target 现在是 inner 的引用。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.inner()>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 装饰器通常把函数替换成另一个函数
def deco(func):
    def inner():
        print('running inner()')
        return func()
    return inner # deco 返回 inner 函数对象

@deco
def target(): # 使用 deco 装饰 target。
    print('running target()')

# target = deco(target) # 有了语法糖这句可以省略  相当于 target = wrapper
target() # 调用被装饰的 target 其实会运行 inner。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
running inner()
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
registry = [] # registry 保存被 @register 装饰的函数引用。

def register(func):  # register 的参数是一个函数。
    print('running register(%s)' % func) # 为了演示,显示被装饰的函数。
    # func.__name__ 显示被装饰函数的名字
    registry.append(func)  # 把 func 存入 registry。
    return func # 返回 func:必须返回函数;这里返回的函数与通过参数传入的一样。

@register 
def f1():
    print('running f1()')
    
@register
def f2():
    print('running f2()')

def f3(): 
    print('running f3()')
    
def main(): # main 显示 registry,然后调用 f1()、f2()f3()print('running main()')
    print('registry ->', registry)
    f1()
    f2()
    f3()
    
if __name__=='__main__':
    main() 
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
running register()
running register()
running main()
registry -> [, ]
running f1()
running f2()
running f3()

注意,register 在模块中其他函数之前运行(两次)。调用register 时,传给它的参数是被装饰的函数,例如 。

上面例子主要想强调,函数装饰器在导入模块时立即执行,而被装饰的函数只在明确调用时运行。这突出了 Python 程序员所说的导入时和运行时之间的区别。

考虑到装饰器在真实代码中的常用方式,上面例子有两个不寻常的地方。

  • 装饰器函数与被装饰的函数在同一个模块中定义。实际情况是,装饰器通常在一个模块中定义,然后应用到其他模块中的函数上。
  • register 装饰器返回的函数与通过参数传入的相同。实际上,大多数装饰器会在内部定义一个函数,然后将其返回。

[1] 廖雪峰 装饰器 [2] 流畅的python

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=29v0kx6sv4w0s

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/06/22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python函数装饰器基础知识
函数装饰器是Python语言最优秀的设计之一,它以非常简洁的方式增强了函数的行为,让崎岖不平之路变得平坦顺畅。
dongfanger
2022/05/09
2680
Python函数装饰器基础知识
python 装饰器
文章目录 1. 装饰器在导入的时候就会执行 2. functools.wraps 装饰器,保持 被装饰的函数的 `__name__` 的值不变 3. functools.lru_cache 实现备忘录 4. functools.singledispatch 处理多个不同的输入类型 5. 堆叠装饰器 6. 参数化装饰器 learn from 《流畅的python》 def deco(func): def inner(): print("running inner()") r
Michael阿明
2021/09/06
4140
Python 装饰器使用指南
装饰器的一大特性是,能把被装饰的函数替换成其他函数。第二大特性是,装饰器在加载模块时立即执行。
goodspeed
2020/12/22
5360
Python 装饰器使用指南
Python 函数装饰器和闭包
创建一个装饰器工厂函数,把参数传给它,返回一个装饰器,然后再把它应用到要装饰的函数上。
为为为什么
2022/08/09
6980
Python 函数装饰器和闭包
python基础-装饰器笔记
函数装饰器用于在源码中“标记”函数,以某种方式增加函数的行为。这是一项强大的功能,但是若想要掌握,必须理解闭包。
zx钟
2019/07/19
5610
python 中的装饰器及其原理
熟悉 Java 的程序员一定对 Java 中强大的注解有所了解,Python 在一定程度上受到了 Java 的影响,诞生了 Python 的装饰器特性。 Python 的装饰器是一个非常强大的功能,本文我们就来详细介绍一下 Python 的装饰器特性。 例如我们熟知的类静态方法在定义时就常常会使用 @staticmethod 与 @classmethod 装饰器:
用户3147702
2022/06/27
6350
python 中的装饰器及其原理
Python之@函数装饰器
装饰器的作用 —— 不想修改函数的调用方式 但是还想在原来的函数前后添加功能 原则: 开放封闭原则 开放 : 对扩展是开放的 封闭 : 对修改是封闭的
cuijianzhe
2022/06/14
4420
Python之@函数装饰器
流畅的 Python 第二版(GPT 重译)(五)
函数装饰器让我们在源代码中“标记”函数以增强其行为。这是强大的东西,但要掌握它需要理解闭包—当函数捕获在其体外定义的变量时,我们就得到了闭包。
ApacheCN_飞龙
2024/03/21
2120
流畅的 Python 第二版(GPT 重译)(五)
Python函数装饰器高级用法
函数装饰器和闭包紧密结合,入参func代表被装饰函数,通过自由变量绑定后,调用函数并返回结果。
dongfanger
2021/06/10
9160
Python函数装饰器高级用法
Python装饰器的详细解析
Python装饰器(fuctional decorators)就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。
用户8949263
2022/04/08
5910
理解Python 装饰器
装饰器应该是我学习Python时,第一个遇到的难题,当时看了很多教程,最终理解并在工作中使用,是stackoverflow这篇文章:stackoverflow装饰器
用户7886150
2020/12/19
3340
python Function(函数)
函数是python为了代码最大程度地重用和最小化代码冗余而提供的基本程序结构。函数是一种设计工具,它能让程序员将复杂的系统分解为可管理的部件; 函数用于将相关功能打包并参数化。 在python中可以创建如下4种函数:     1)、全局函数:定义在模块中(直接定义在模块中的函数)。     2)、局部函数:嵌套于其它函数中(在函数中再定义的函数)。     3)、lambda函数:表达式。匿名函数(它仅是一个表达式),它可以出现在任何位置,很高的录活性。     4)、方法:与特定数据类型关联的函数,并且只能与数据类型相关一起使用。定义在类中的函数。    python也提供了很多内置函数 函数与过程的区别:     函数都有return返回值。返回一个对象 创建函数     def functionName(parameters):         suite 相关概念:     def 是一个可执行语句;因此可以出现在任何能够使用的地方,甚至可以嵌套于其它语句,例if或while中。def创建了一个对象  并将其赋值给一个变量名(即函数名);     return用于返回结果对象,其为可选项;无return语句的函数自动返回一个None对象;返回多个值时,彼此间使用逗号分隔,且组合为元组形式返回一个对象。     def语句运行之后,可以在程序中通过函数名后附加括号进行调用 。     例1:
py3study
2020/01/13
8010
一文读懂python装饰器由来(二)
上一篇文章主要以一步一步演进的方式介绍了装饰器的工作原理以及使用(没看的小伙伴可以关注一下 一文读懂Python装饰器由来(一)),其实只要认真学习上一篇文章,已经能够满足日常对装饰器的使用了。但是,若想真正理解装饰器,并进行更高阶的使用还要了解其他一些知识:
Python中文社区
2018/07/26
4500
python 装饰器理解
在理解装饰器之前,先应该对闭包有个概念:所谓闭包,就是将组成函数的语句和这些语句的执行环境打包在一起时得到的对象,它的主要作用是封存上下文。这一特性可以巧妙的被用于现有函数的包装,从而为现有函数添加功能,这就是装饰器。
py3study
2020/01/07
4100
深入了解Python中的装饰器
Python的装饰器是AOP编程的一种实现,其他很多语言也都支持装饰器模式。 注:AOP是指面向切面编程,详见 AOP概念
tunsuy
2022/10/27
3500
《流畅的Python》第七章学习笔记
闭包指延伸了作用域的函数,其中包含了「函数定义体中引用」、「不在定义体中定义的非全局变量」
zx钟
2020/12/24
4410
【Python基础之函数:多层语法糖、装饰器和装饰器修复技术及递归函数】
​ 多层语法糖是指在单个源代码函数名上方添加了多个语法糖,使这段源代码函数体具备多个功能
老虎也淘气
2024/01/30
2370
【Python基础之函数:多层语法糖、装饰器和装饰器修复技术及递归函数】
Python3中的装饰器
def foo(): print("第一次定义的foo()函数") def foo(): print("第二次定义的foo()函数") foo() # 结果 第二次定义的foo()函数
py3study
2020/01/10
6220
开源图书《Python完全自学教程》7.3.4装饰器
函数 book() 是一个普通的函数,函数 p_decorate() 是嵌套函数,外层函数的参数 func 所引用的对象必须可执行,并且是 func(name) 形式,正好 book() 函数可以满足(其它满足要求的函数亦可,这里仅以 book() 为例)。根据对嵌套函数的理解,注释(17)得到了闭包,注释(18)执行写在 p_decorate() 函数里面的 wrapper() 函数对象。最后打印返回值。
老齐
2022/07/06
3870
Python 中的装饰器
一, 引用 [书] 流畅的Python [书] Effective Python 二, 基本概念 问题1:装饰器是什么? 解答: 严格来说,装饰器只是语法糖, 装饰器是可调用的对象,可以像常规的可调用对象那样调用,特殊的地方是装饰器的参数是一个函数 问题2:装饰器有什么特性? 解答: 装饰器有2个特性,一是可以把被装饰的函数替换成其他函数, 二是可以在加载模块时候立即执行 def decorate(func): print('running decorate', func) def decor
小小科
2018/05/02
1.2K0
Python 中的装饰器
相关推荐
Python函数装饰器基础知识
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验