【Python】学习笔记——-5.4、装饰器

编写一个decorator,能在函数调用的前后打印出'begin call'和'end call'的日志 注意:我们要借助Python的@语法,把decorator置于函数的定义处初步尝试:def log(func): def wrapper(*args, **kw): print 'begin call: %s' %func.__name__ return func(*args, **kw) print 'end call: %s' %func.__name__ return wrap... 阅读详情

由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。

>>> def now():
...     print('2015-3-25')
...
>>> f = now
>>> f()
2015-3-25

函数对象有一个__name__属性,可以拿到函数的名字:

>>> now.__name__
'now'
>>> f.__name__
'now'

现在,假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

本质上,decorator就是一个返回函数的高阶函数。所以,我们要定义一个能打印日志的decorator,可以定义如下:

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

观察上面的log,因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。我们要借助Python的@语法,把decorator置于函数的定义处:

@log
def now():
    print('2015-3-25')

调用now()函数,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志:

>>> now()
call now():
2015-3-25

把@log放到now()函数的定义处,相当于执行了语句:

now = log(now)

由于log()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数。

wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。

如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

这个3层嵌套的decorator用法如下:

@log('execute')
def now():
    print('2015-3-25')

执行结果如下:

>>> now()
execute now():
2015-3-25

和两层嵌套的decorator相比,3层嵌套的效果是这样的:

>>> now = log('execute')(now)

我们来剖析上面的语句,首先执行log('execute'),返回的是decorator函数,再调用返回的函数,参数是now函数,返回值最终是wrapper函数。

以上两种decorator的定义都没有问题,但还差最后一步。因为我们讲了函数也是对象,它有__name__等属性,但你去看经过decorator装饰之后的函数,它们的__name__已经从原来的'now'变成了'wrapper':

>>> now.__name__
'wrapper'

因为返回的那个wrapper()函数名字就是'wrapper',所以,需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。

不需要编写wrapper.__name__ = func.__name__这样的代码,Python内置的functools.wraps就是干这个事的,所以,一个完整的decorator的写法如下:

import functools

def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

或者针对带参数的decorator:

import functools

def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

import functools是导入functools模块。模块的概念稍候讲解。现在,只需记住在定义wrapper()的前面加上@functools.wraps(func)即可。

小结

在面向对象(OOP)的设计模式中,decorator被称为装饰模式。OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。Python的decorator可以用函数实现,也可以用类实现。

decorator可以增强函数的功能,定义起来虽然有点复杂,但使用起来非常灵活和方便。

请编写一个decorator,能在函数调用的前后打印出'begin call'和'end call'的日志。

再思考一下能否写出一个@log的decorator,使它既支持:

@log
def f():
    pass

又支持:

@log('execute')
def f():
    pass
5个高频python装饰器使用场景 大家好,我是志军,10年Python经验这是Python必知必会系列的第5篇Python装饰器是一个非常实用的功能,它允许程序员修改或增强现有函数或方法的行为,而不需要修改原始代码。装饰器本质上是一个函数,这个函数可以接受另一个函数作为参数,并返回一个新的函数。在本文中,我将分享5个装饰器的高频率使用场景,并通过实际示例来说明如何使用它们。 阅读详情

相关推荐

python的高级4——闭包、装饰器

本文介绍了Python中的闭包和装饰器概念。闭包是指内部函数引用外部函数变量的结构,具有保存状态和数据隐藏的作用。装饰器是闭包的特殊应用,通过接受函数作为参数并返回新函数来扩展功能,使用@语法简化调用。文章详细讲解了闭包和装饰器的特点、实现方式、常见应用场景及注意事项,并分析了两者关系:装饰器建立在闭包基础上,专门用于函数行为修改。最后介绍了内置装饰器如@property、@classmethod的使用方法。

weixin_56449709的博客 859

python 装饰器

由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。 >>> def now(): ... print '2013-12-25' ... >>> f = now >>> f() 2013-12-25 函数对象有一个__name__属性,可以拿到函数的名字: >>> ...

weixin_33843947的博客 218

使用【阿里云百炼】搭建自己的大模型

本文介绍阿里云百炼大模型平台,其为企业级服务平台,融合通义千问等模型,支持多模态能力,提供一站式工具降低开发门槛。重点讲解智能体应用及大模型搭建步骤,含进入创新应用界面、选模型配参数、输指令、导数据、加载知识库、获取API Key、加样例库、配置MCP,还提及模型调试与多平台发布,并附试用链接,助力企业与开发者快速搭建适配业务的AI模型。

Larry的博客 4738

设计一个decorator,可作用于任何函数上,并打印该函数的执行时间

Python新手,学习廖雪峰老师的Python教程。 此题出处为廖雪峰老师的官方网站的装饰器一节。 import time,functools def _time(func): @functools.wraps(func) def wrapper(*args,**kw): t1 = time.time() a = func(*args,**kw) print('%s execute in %s ms'%(func.__name__,100*(time.time()-t1))) retur

Ram_2020 519

NXP ChessDE的安装和激活

如果客户申请的是试用版,那么一份为期 30 天的 License 将会发送申请人的账号或邮箱中,客户使用该文件进行安装即可。② 将“VENDOR snpslmd /path/to/snpslmd”中的“/path/to/snpslmd”替换成 snpslmd.exe 实际存放路径(位于 SCL 安装目录下的 win32\bin 文件夹中,默认安装的情况下就是“VENDOR snpslmd C:\Synopsys\SCL\<version>\win32\bin\snpslmd.exe”)。

weixin_47351160的博客 2044

波克 上海 Unity开发笔试题 2024

主要分为四部分,如果没有准备好,不要点击笔试链接,进入就会自动开始。

z2014z的博客 3396

请编写一个decorator,能在函数调用的前后打印出‘begin call‘和‘end call‘的日志

题目来源: 廖雪峰的官方网站 题目: 请编写一个decorator,能在函数调用的前后打印出’begin call’和’end call’的日志 本题思路借鉴此文大佬,难点在于如何显示调用函数后的日志。 RonnyChan 代码如下: def log(func): def wrapper(*args, **kw): print('begin call') c = func(*args, **kw) print('end call') r

qq_48751632的博客 678

基于STM32F103与AD8232的便携式心电监测系统设计与实现

本文详细介绍基于STM32F103微控制器与AD8232心电传感器模块的便携式心电监测系统设计与实现。系统通过ADC采集心电信号,结合软件滤波算法处理基线漂移和工频干扰,并利用OLED屏幕实时显示波形,具有低成本、高实用性的特点,适用于健康监测与嵌入式学习。

m5n6o7的博客 737

python学习--decorator练习

今天进入第五天学习了,学到 了装饰器,decorator,结尾有个练习: 请编写一个decorator,能在函数调用的前后打印出 'begin call' 和 'end call' 的日志。 再思考一下能否写出一个 @log 的decorator,使它既支持: @log def f():         pass 又支持: @log('execute') def f():

malinda666的博客 1019

Arduino for ESP32-----ESP-NOW介绍及使用

ESP-NOWESP-NOW介绍ESP-NOW支持以下特性ESP-NOW技术也存在以下局限性获取ESP32的MAC地址ESP-NOW单向通信(One-way communication)ESP32单板间的双向通信一对多通信(一发多收)一对多通信(多发一收) ESP-NOW介绍 ESP-NOW是一种由Espressif开发的协议,可以让多个设备在不使用Wi-Fi的情况下相互通信。该协议类似于低功耗的2.4GHz无线连接。设备之间的配对需要在通信之前完成。配对完成后,连接是安全的、点对点的,不需要握手。这意味着

Better_man1的博客 2万+

3分钟学会SQL中的断点去重技术,轻松搞定连续重复数据去重问题?

传感器采集的温度数据中,存在连续重复的值,需仅在数值变化时保留记录(例如:温度从 25°C 变为 26°C 时记录一次)。:判断逻辑,current_value!若当前温度与前一行的温度不同(或为第一条记录),则保留该行。的技术,常用于时间序列或状态日志中。:将连续相同值的记录合并,只保留断点处的记录。保留断点处的记录(即温度变化时的第一条)。原始数据表 sensor_data。最终仅保留值变化的断点记录。获取前一行的温度值。

石榴姐yyds 1019

python-装饰器

Python 中的装饰器是一种语法糖,可以在运行时,动态的给函数或类添加功能。装饰器本质上是一个函数,使用@ + 函数名就是可实现绑定给函数的第二个功能。将一些通用的、特定函数的功能抽象成一个装饰器,可以重复利用这些功能“装饰”代指为被装饰对象添加新的功能,“器”代指器具/工具装饰器的作用:就是在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能。插入日志、性能测试、事务处理、缓存、权限校验函数、方法、类函数装饰器分为:无参装饰器和有参装饰,二者都是使用都是需要【

王献运的博客 2万+

DataEase 未授权+远程代码执行漏洞复现(CVE-2025-49001、CVE-2025-49002)

DataEase 是一款开源的数据分析平台,提供丰富的数据可视化和分析功能,帮助用户轻松地进行数据探索和决策支持。近日,有关DataEase 被爆出多个漏洞,其中 CVE-2025-49001 是由于JWT校验机制错误导致攻击者可伪造JWT令牌绕过身份验证流程,CVE-2025-49002 是由于H2数据库模块没有严格过滤用户输入的JDBC连接参数,可使用大小写绕过补丁。攻击者可利用这些漏洞实现未授权代码执行,威胁用户数据和系统的安全。

李同學AI安全 1947

python 类的使用(5)之类装饰器(类的装饰器和类作为装饰器)

在Python中,类可以作为装饰器,同时也能被函数装饰器所装饰。本文简要介绍了类作为装饰器和函数装饰器装饰类的使用方式,有兴趣的不要错过啊!

keepaware的博客 2万+

C#上位机+YOLO实战:从环境搭建到实现首个目标检测(零基础入门)

/ YOLOv8的类别名称(共80类,对应COCO数据集)// ONNX推理会话// YOLOv8的输入宽度// YOLOv8的输入高度本文从技术选型、环境搭建到代码实现,详细介绍了如何将C#上位机与YOLOv8结合,实现基础的目标检测功能。整个过程避开了常见的坑点,同时对核心原理和代码逻辑进行了详细解析,希望能帮助零基础的开发者快速入门。实际上,C#上位机+YOLO的组合在工业领域有非常广泛的应用,本文的案例只是一个起点。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 791

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【Python】装饰器

装饰器是 Python 中的一个强大工具,允许你在不改变函数本身的代码情况下,动态地修改或扩展其行为。装饰器通常用于日志记录、权限验证、缓存、性能监控等应用。你可以使用@decorator语法将装饰器应用到函数或方法上。装饰器是高阶函数,可以接受函数作为参数并返回一个新函数。

wq6qeg88的博客 2277

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Python 装饰器

Python 装饰器(Decorator)是一种用于修改或扩展函数或方法行为的工具。它允许在不改变原函数代码的情况下,动态地添加功能。装饰器本质上是一个闭包函数,接受一个函数作为参数并返回一个新的函数。

大龄程序员 6033

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

python3:装饰器的5大用法总结

装饰器,顾名思义,就是给函数作装饰作用的,相当于只是给函数化了一个装,并没有给他添加额外的代码,但是却增加了新功能,就如同我们在冬天很冷的情况下,想要变暖和(添加新功能),但是我们不是生活在武侠小说里有内功,肿么办?我们可以穿一件羽绒服来保暖(这件羽绒服就相当于是装饰器了) 装饰器的内部实现原理就不讲了,这里只是装饰器的5种形式,搞定了,其本就完全明白了装饰器的的有用法。 1. 定义普通不带参数的...

lxy210781的专栏 6168

Python装饰器:函数装饰器①

func()我们可以使用")Hello!在这个例子中,是一个装饰器,它接受函数say_hello作为参数,并返回一个新的函数wrapper。当调用say_hello时,实际上调用的是wrapper函数。装饰器是 Python 中一个非常强大的工具,可以用来扩展和修改函数或方法的行为。通过装饰器,我们可以在不修改原始代码的情况下为函数添加额外的功能。在实际开发中,装饰器有很多应用场景,包括日志记录、访问控制、性能优化等。希望本文能够帮助你更好地理解和使用 Python 中的装饰器。

结合项目案例,记录点点滴滴,自己回顾,分享他人o__o 2901

Python装饰器:类装饰器②

类装饰器与函数装饰器类似,只不过它们接受一个类作为参数,并返回一个新类。obj.new_method() # 调用新增的方法obj.existing_method() # 调用被重写的方法在这个例子中,是一个类装饰器,它接受一个类MyClass作为参数,并返回一个新的类。继承自MyClass,并新增和重写了一些方法。类装饰器是 Python 中一个非常强大的工具,可以用来扩展和修改类的行为。通过类装饰器,我们可以在不修改原始代码的情况下为类添加额外的功能。

结合项目案例,记录点点滴滴,自己回顾,分享他人o__o 3552

python装饰器

Python装饰器是一种非常强大的功能,它允许用户在不修改原始函数定义的情况下,给函数添加额外的功能。装饰器本质上是一个接受函数作为参数的函数,它返回一个新的函数,这个新函数通常会在执行原始函数之前或之后增加一些额外的操作。

m0_45334833的博客 1286

Python 深入浅出装饰器

本文详细介绍了Python装饰器的概念与应用。装饰器本质上是接受函数并返回新函数的高阶函数,通过@语法为原函数添加额外功能(如日志、计时、权限验证等)。文章从函数基础知识(如闭包)讲起,通过计时器示例演示装饰器原理,并扩展了带参数装饰器、类装饰器和多重装饰器等高级用法。实际应用场景包括日志记录、权限验证和缓存优化等,展示了装饰器如何提升代码复用性和可维护性。

余子越的博客 1408

Python 装饰器的学习笔记

Python 装饰器的学习笔记

engchina的专栏 702

python装饰器的全面总结学习笔记

之前了解过Python中的装饰器、生成器和迭代器的概念,并没有系统的深入了解,平时写代码基本也没有碰到过这样的场景需求。最近在看tensorflow2.0框架相关的框架的时候,看到了装饰器,作用不是很熟悉,觉得有必要做一个系统的学习,然后记录下来,加深理解同时以备后续复习。 ...

HUSTHY的博客 570

Python - 装饰器

Python装饰器是一种强大的语法特性,允许在不修改原函数代码的情况下动态扩展函数行为。装饰器本质上是高阶函数,接收函数作为参数并返回新函数。文章介绍了基础装饰器、带参数装饰器、类装饰器的实现方式,以及@staticmethod、@classmethod、@property等内置装饰器的用法。此外还展示了装饰器在测试中的应用(如数据驱动测试和Mock测试),并解释了装饰器的执行顺序。掌握装饰器可以使代码更简洁灵活,适用于日志记录、性能测试、权限控制等多种场景。

m0_60008263的博客 1305

python装饰器理解

python装饰器@

weixin_45034895的博客 1591
上一篇: 【Python】学习笔记——-5.3、匿名函数
下一篇: 【Python】学习笔记——-5.5、偏函数
白衣染霜陈
博客等级 码龄22年 682粉丝 338原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值