| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
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里面最后打印“执行顺序④” 
 
 
 
结合下面这一张蠢蠢的手绘图(字丑人更丑  )看上面步骤,应该能好理解不少: 
 
 
 
 
 
 
 
 
 
 
 
 
 |   
 
评分
- 
查看全部评分
 
 
 
 
 
 |