马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 heidern0612 于 2018-12-25 17:54 编辑
写心得的过程都是自我思考的过程,借鉴了很多论坛前辈和互联网大佬的经验,仓促间难免有错,恳请指出,不胜感激。
Marry Christmas!!!
文章部分转载自伯乐在线帖子,原贴地址:戳我前进
首先引入装饰器相关:
1、@修饰符的定义:
‘@’修饰符必须出现在函数定义前一行,不允许和函数定义在同一行。
也就是说以下代码是非法的:
只可以在模块或类定义层内对函数进行修饰,不允许修饰一个类。
@修饰符更像是装饰器的一个浓缩,一个语法糖,那么,什么是装饰器呢?
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()
输出结果:
不看后面答案小朋友们能想出来为啥输出结果会是这样的吗?
难道结果不应该是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里面最后打印“执行顺序④”
结合下面这一张蠢蠢的手绘图(字丑人更丑 )看上面步骤,应该能好理解不少:
|