Python装饰器实例讲解(三)
1|0Python装饰器实例讲解(三)
本文多参考《流畅的python》,在此基础上增加了一些实例便于理解
姊妹篇
Python装饰器实例讲解(一),让你简单的会用
Python装饰器实例讲解(二),主要讲了一个万能公式(原理)
本文其实反而是最最基础的部分,当然也回答了好几个关键的问题,也有一些是重复的地方
- 理解装饰器必须理解函数、闭包等概念
- 闭包后面单独讲,函数在本文是重点,从函数讲起
1|1函数:一等对象
- 在Python中,函数是一等对象,需要满足以下条件:
- 在运行时创建
- 能赋值给变量或数据结构中的元素
- 能作为参数传给函数
- 能作为函数的返回结果
- 在Python中,整数、字符串和字典都是一等对象
函数名能赋值给变量
-
示例
-
这样的使用比比皆是,比如在pytest中的一个应用
-
较为为典型的应用就是lambda,它是匿名的,但它同样可以赋值给一个变量
函数能作为参数传给函数
-
示例
-
在上面的例子中你可以看到calc这个函数接收的第一个参数是函数名字
-
调用的时候你传入的是double、triple这样的名字
-
仔细观察代码,calc的实现其实的本意就是把第一个参数当做函数名,第二个参数是第一个参数的参数。所以本质上你可以做任何事情,只要这个函数仅接收一个参数即可
-
高阶函数如map/filter/reduce/sort等,如果你接触过,他们的参数不都是函数名吗?
-
我也写过一篇文章,Python函数式编程之map/filter/reduce/sorted
能作为函数的返回结果
-
示例
-
你也可以这样
-
如果你看过前面的两篇文章,到这里就应该很熟悉了
1|2可调用对象
-
除了函数是可调用的,还有很多(其实也没多少)都是可调用对象
-
按照流畅的python的说法,有这么多可调用对象
可调用对象 说明 用户定义的函数 使用 def 语句或 lambda 表达式创建 内置函数 使用 C 语言(CPython)实现的函数,如 len 或 time.strftime 内置方法 使用 C 语言实现的方法,如 dict.get 方法 在类的定义体中定义的函数 类 调用类时会运行类的 new 方法创建一个实例,然后运行 init 方法,初始化实 例,最后把实例返回给调用方。因为 Python 没有 new 运算符,所以调用类相当于调用函数。 类的实例 如果类定义了 call 方法,那么它的实例可以作为函数调用。 生成器函数 使用 yield 关键字的函数或方法。调用生成器函数返回的是生成器对象。
对普通的初学者而言其实就是函数和类,类的调用分2级,Obj()这是实例化,同时调用new和init。
new和init魔术方法,后面会单独开篇讲解,单例跟这个是息息相关的。
生成器后面也考虑单独开文章说一下。
-
示例代码(说明new和init)
-
示例输出
-
但此时wuxianfeng这个Person类的实例并不是可调用的对象
-
如果你写wuxianfeng(),会给你提示
-
你需要在Person类中定义一个__call__方法
-
此时再次执行wuxianfeng()就可以得到callable了
-
当然如果你执行Person()()结果也是这样的
-
python提供了一个内置的callable()函数来检测对象是否可调用
1|3回到装饰器
-
虽然你可能已经学到装饰器三了,但请你清空下你了解的装饰器,倒也不是从0开始,带点复习
-
示例代码
-
输出结果
-
根据万能公式,分析下执行过程
-
当你在执行target()的时候,由于target上有个装饰器,实际上发生的事情是target = decorate(target)
-
前面的target 是新的(一个变量),后面的decorate(target)中的target是你之前定义的函数
-
decorate(target)就会去调用decorate函数传入target参数,返回inner
-
卡....返回了inner,是你加了装饰器的效果,至此都没有执行函数
-
正是由于最终的target(),就是去调用了inner(),对应的语句是
-
- 说一些理论
- 装饰器只是语法糖
- 装饰器可以像常规的可调用对象那样调用,其参数是另一个函数(被装饰的函数)。
- 装饰器可能会处理被装 饰的函数,然后把它返回,或者将其替换成另一个函数或可调用对象。
- 装饰器的一大特性是,能把被装饰的函数替换成其他函数
- 第二个特性是,装饰器在加载模块时立即执行
-
关于被替换
-
示例输出(你输出的id跟我肯定不一样,但2者应该是一致的,从这个角度也能看出来你执行的target不再是原来的target了)
1|4叠放装饰器
-
日常代码中还是有一些场景能看到一个函数被多个装饰器装饰的情况,比如pytest的allure
-
这个执行顺序就是如你所想的那般,挨的最近的先执行
-
示例代码
-
但这种情况下的万能公式是怎样的呢???你知道不~
-
万能公式1
-
万能公式2
-
不信请看
- 装饰器就讲到这里了
- 会用是第一步,理解简单的过程是第二步,会写一个装饰器才算是基本懂了
__EOF__

本文链接:https://www.cnblogs.com/wuxianfeng023/p/17126324.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)