鱼C论坛

 找回密码
 立即注册
查看: 3361|回复: 7

[学习笔记] Wrapper的语法糖---"@"函数修饰符和装饰器

[复制链接]
发表于 2018-12-25 16:29:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 heidern0612 于 2018-12-25 17:54 编辑

写心得的过程都是自我思考的过程,借鉴了很多论坛前辈和互联网大佬的经验,仓促间难免有错,恳请指出,不胜感激。



Marry Christmas!!!


文章部分转载自伯乐在线帖子,原贴地址:戳我前进


首先引入装饰器相关:

1、@修饰符的定义:

‘@’修饰符必须出现在函数定义前一行,不允许和函数定义在同一行。

也就是说以下代码是非法的:
@A    def f(): 


只可以在模块或类定义层内对函数进行修饰,不允许修饰一个类。

@修饰符更像是装饰器的一个浓缩,一个语法糖,那么,什么是装饰器呢?




2、装饰器作用:

Python的修饰器的英文名叫Decorator。

装饰器的作用是什么呢? 简单的理解就是:装饰原有的函数。(可以想象成普通的松树,圣诞节时装饰上各种美丽的彩灯和彩带。)

比如有一个函数func(a, b),它的功能是求a,b的差值。

我现在有一个需求,就是想对函数功能再装饰下,求完差值后再取绝对值,但是不能在func函数内部实现,这时候就需要装饰器函数了。

比如func = decorate(func)函数,将func函数作为参数传递给decorate函数,由decorate来丰富func函数,丰富完成后再返回给func,此时func的功能就丰富了。

以上有木有感觉很熟悉,函数调用自身,修饰完毕后再返回自身,像不像闭包?



Python的函数修饰符,“@”,与其说是修饰函数倒不如说是引用、调用它修饰的函数。

举个栗子:
def test(f):
    print "before ..."
    f()
    print "after ..."
 
@test
def func():
    print "func was called"

直接运行,输出结果:
before ...
func was called
after ...

上面代码可以看出来,只定义了两个函数: test和func,没有调用它们,如果没有“@test”,运行应该是没有任何输出的


但是,Python解释器读到函数修饰符“@”的时候,后面步骤会是这样了:

1. 去调用 test函数,test函数的入口参数就是那个叫“func”的函数;

2. test函数被执行,入口参数的(也就是func函数)会被调用(执行);

换言之,修饰符带的那个函数的入口参数,就是下面的那个整个的函数。



以上需要注意的是:

1. 函数必须先定义,才能修饰它,反之的话会编译器不认识;

2. 修饰符“@”后面必须是之前定义的某一个函数;

3. 每个函数只能有一个修饰符,大于等于两个则不可以。






最后再看一个有趣的栗子,有关多个@执行顺序的问题

def test3(func3):
    func3()
    print ("执行顺序3")

def test4(func4):
    func4()
    print ("执行顺序4")


def main():
    @test4
    def func1():
        print ("执行顺序1")
        @test3
        def func2():
            print( "执行顺序2")
main()

输出结果:
执行顺序1
执行顺序2
执行顺序3
执行顺序4



不看后面答案小朋友们能想出来为啥输出结果会是这样的吗?

难道结果不应该是4132吗?1234是什么鬼?

咳咳……



实例解析如下:

①、main函数执行,内部两部分:@test4 和  def func1()。

②、@test4包裹在 def func1()外面,调用test4的函数test4(fun4),这里fun4是形参,而实际上func1()是个实参。

③、实参传入进去,首先打印出来的就是“执行顺序①”。 func1()内部也分两部分,一部分是@test3,def func2()。

④、同②道理,test3(func3),这里func3是形参,而实际传入的是fun2()实参。fun2()传入直接打印“执行顺序②”,调用完毕后执行test3里的print,打印“执行顺序③

⑤、一步步返回上一级,返回到①里,test4里面最后打印“执行顺序④



结合下面这一张蠢蠢的手绘图(字丑人更丑 )看上面步骤,应该能好理解不少:
微信图片_20181225162832.jpg










评分

参与人数 5荣誉 +14 鱼币 +9 贡献 +2 收起 理由
小伤口 + 1 + 1 感谢楼主无私奉献!
hhhhhhy + 5
Twilight6 + 1 + 1 嗯 感觉懂了些!
嗷呜呜呜 + 4 + 4 + 2 感谢楼主无私奉献!
冬雪雪冬 + 3 + 3

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-1-17 19:17:27 | 显示全部楼层
66666666666,简单易懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-10 14:43:40 | 显示全部楼层
顶下哈哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-5 10:34:42 | 显示全部楼层
感谢楼主
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-12 10:55:12 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-13 23:26:21 | 显示全部楼层
有点明白了,感谢感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-20 22:36:46 | 显示全部楼层
终于看懂了,谢谢大佬
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-11 10:38:30 | 显示全部楼层
通俗易懂,赞
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-22 08:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表