Python装饰器:简单易懂的函数增强技巧
创始人
2024-12-29 18:16:41
0 次浏览
0 评论
如何最简单、通俗地理解python的装饰器?
装饰器是一种Python技术,可以在不修改原始功能代码的情况下添加额外的功能。它的本质是一个闭包函数。
装饰器的主要特点是它只添加一个新的函数,而不修改原函数的源代码和调用方法。
闭包和装饰器之间的主要区别在于,如果闭包只有一个参数并且是一个函数,那么该闭包就是一个装饰器。
遵循开放和封闭的原则,使得功能代码不能修改但可以扩展。
这是装饰器的一个重要应用。
示例代码展示了如何通过应用装饰器自动装饰函数。
装饰器的语法糖通过在函数之前使用“@decorator_name”而不是多次调用“func=decorator(func)”来简化过程。
装饰器的运行时是当前模块加载时,立即执行装饰器来装饰现有功能。
装饰器的常见使用场景包括函数执行时间统计、输出日志信息等。
通用装饰器可以用来装饰任何类型的函数,并且内部函数类型必须与要装饰的函数类型相匹配。
多个装饰器的使用遵循从内到外的顺序,首先执行内层装饰器,然后执行外层装饰器。
带参数的装饰器在使用时以“@decorator(parameters...)”的形式添加。
这基本上将函数包装在装饰器外部,接收参数并返回装饰器实例。
类装饰器通过类实例化来装饰现有函数来封装函数。
装饰器涵盖了广泛的应用场景,包括日志记录、权限检查、运行时计算、数据库操作、缓存、数据序列化和反序列化等等。
分享经验:学习Python时,最好选择自己写代码的视频,通过自己写代码来理解逻辑。
寻找点击率高的优质教育视频,寻找能够激发学习兴趣的老师。
验证知识时,主动调试代码并输出变量值,以确定程序执行状态。
加入学习小组并通过问答加深您的理解。
学习时避免常见的误解。
遇到模糊的知识点,首先要了解原理。
即使你目前正在实现一个需求,你也应该继续学习知识来提高你的理解。
通过向别人解释知识点或主题,你加深了自己的理解和记忆。
这样做不仅可以提高你对知识的理解深度,还可以增强你的记忆力。
我的分享旨在帮助大家提高Python学习效率,希望对大家有所帮助。
如何理解Python装饰器
装饰器基本上是一个Python函数,其返回值也是一个函数对象,允许在不更改代码的情况下添加其他函数。记录条目;性能测试;交易处理;缓存;常用于有截断需求的场合,例如授权验证。
装饰器是解决此类问题的绝佳设计,因为装饰器可以提取大量与函数本身无关的相似代码并继续使用它。
简而言之,装饰器的目的是向现有对象添加附加功能。
我们先看一个简单的例子:deffoo():print('iamfoo')现在我们希望记录函数的执行日志,所以我们在代码中添加日志代码:deffoo():print('iamfoo')logging.info("fooisrunning")bar()和bar2()具有类似的要求。
在bar函数中写入另一条记录。
它可以重新定义专门运行日志的函数,减少重复编码sisrunning"%func.__name__)func()defbar():print('iambar')use_logging(bar)逻辑上不难理解,但在这种情况下,我们必须将一个函数作为参数传递给use_logging函数,另外,这个方法之前构造了原始代码逻辑。
当业务逻辑执行时;bar()已完成,但现在已更改为use_logging(bar)。
那么有没有更好的办法呢?当然,答案是装饰器。
简单装饰器defuse_logging(func):defwrapper(*args,**kwargs):logging.warn("%sisrunning"%func.__name__)returnfunc(*args,**kwargs)returnwrapperdefbar():print('iambar')bar=use_logging(bar)bar()函数use_logging是一个装饰器,看起来函数内部执行实际业务方法的bar是用use_logging装饰的。
在这个例子中,当函数进入和退出时,称为切面,这种编程方法称为面向切面编程。
@符号用于定义函数以避免再次赋值defuse_logging(func):defwrapper(*args,**kwargs):logging.warn("%sisrunning"%func.__name__)。
returnfunc(*args)returnwrapper@use_loggingdeffoo():print("iamfoo")@use_loggingdefbar():print("iambar")bar()如上图;所以可以省略bar=use_logging(bar)和callbar()这句话来获取。
期望的结果。
如果我们还有其他类似的功能;你可以不断地调用装饰器,而无需重复修改函数或添加新的包。
这样,我们提高了程序的可重用性,增加了程序的可读性。
装饰器在Python中使用起来如此方便的原因是Python函数可以像普通对象一样作为参数传递给其他函数。
可以赋值给其他变量并用作返回值也可以在其他功能中进行设置。
带框架的装饰器带框架的装饰器更加灵活,如:@use_logging上面的装饰器调用中;装饰器的唯一参数是执行任务的函数。
装饰器语法在调用时可以支持其他参数,例如@decorator(a)。
这使得写作和使用修饰更加灵活。
defuse_logging(level):defdecorator(func):defwrapper(*args,**kwargs):iflevel=="warn":logging.warn("%sisrunning"%func.__name__)returnfunc(*args)returnwrapperreturndecorator@use_logging(level="warn")deffoo(name='foo'):print("iam%s"%name)foo()上面的use_logging是一个允许参数的装饰器。
事实上,它包装了原始装饰器函数并返回装饰器。
我们可以将其理解为一个带有参数的闭包。
当使用@use_logging(level="warn")调用时,Python可以检测到这个封装层,并将参数传递给装饰器环境。
类装饰器让我们回到类装饰器,与函数装饰器相比,类装饰器提供了更大的灵活性;具有高内聚性和封装性的优点。
您还可以通过使用类装饰器来依赖类内部的\__call\_\_方法;当附加到使用@形式的函数时,装饰器被调用。
classFoo(object):def__init__(self,func):self._func=funcdef__call__(self):print('classdecoratorruning')self._func()print('classdecoratorending')@Foodefbar():print('bar')bar()functools.wraps可以大量重用代码尽管使用了装饰器,但缺少原始函数的元信息(例如docstring和__name__)有一个缺点。
行动的限制清单;先看例子:decoratordeflogged(func):defwith_logging(*args,**kwargs):printfunc.__name__+"known"returnfunc(*args,**kwargs)returnwith_loggingfunction@loggeddeff(x):""doessomemath"""returnx+x*x这个函数是:deff(x):""doessomemath"""returnx+x*xf=logged(f)带有with_logging的函数f找到替代者并不难。
它的文档字符串;__name__成为with_logging函数的数据。
printf.__name__#prints'with_logging'printf.__doc__#printsNone这个问题比较严重;幸运的是,我们还有functools.wraps本身作为装饰器,它可以装饰装饰器的元信息。
这允许装饰函数具有与原始函数相同的元数据。
fromfunctoolimportwrapsdeflogged(func):@wraps(func)defwith_logging(*args,**kwargs):printfunc.__name__+"returnfunc(*args,**kwargs)returnwith_logging@loggeddeff(x):""做一些数学运算"""returnx+x*xprintf.__name__#prints'f'printf.__doc__#prints'doessomemath'内置装饰器的顺序相当于@staticmathod、@property装饰器@a@b@cdeff():f=a(b(f)))。
下一篇:
浪漫编程代码:简单有趣的学习资源盘点
相关文章
Python 1到100计算解析与实例代...
2024-12-17 01:44:32Python Excel文件读取与写入全...
2024-12-28 05:12:12Python字典排序:词汇顺序处理与简单...
2024-12-15 10:20:51Python Shell界面执行.py文...
2024-12-21 21:46:29Python列表与数组:差异解析及适用场...
2024-12-26 02:22:13Python字符串处理技巧:lstrip...
2024-12-15 12:49:15Python安装与下载指南:从官网获取最...
2024-12-15 17:31:16Python pos()函数详解:字符串...
2024-12-20 06:58:26PyCharm快速切换Python版本教...
2024-12-31 04:57:21Python编程:高中与大学学习的差异与...
2024-12-21 06:02:41最新文章
12
2025-01
12
2025-01
12
2025-01
12
2025-01
12
2025-01
12
2025-01
12
2025-01
12
2025-01
12
2025-01
12
2025-01
热门文章
1
Python中的format()方法:字...
formatformat在python中的含义2222.22E+00Format...
2
Python编程入门:全面解析Pytho...
python的基本语法基本的Python语法如下:1.变量的定义。在编程语言中,...
3
Python字符串大小写转换方法全解析
python中字母的大小写转换怎么实现?在Python中,大小写转换由内置函数处...
4
Python字典:轻松获取最小值键与计算...
python在一个字典里,返回值最小元素对应的键,救解在Python字典中,如果...
5
Python字符串去重空格:strip(...
Python去除字符串中空格(删除指定字符)的3种方法在Python编程中,处理...
6
Python数组元素数量计算技巧分享
Python输出数组有多少个元素?简介:在本文中,首席CTO笔记将向您介绍Pyt...
7
简述python中pass的作用
pass语句的作用在许多编程语言中,包括Python;PASS语句用于在代码块中...
8
Python def 关键字详解:函数定...
def是什么意思编程?戴夫是什么意思?def是Python中的函数定义关键字,用...
9
python不区分大小写的方法
Python字符串不区分大小写在Python中,字符串操作默认区分大小写。但有时...
10
Python字典操作全解析:添加、修改、...
Pythondict字典基本操作(包括添加、修改、删除键...