python装饰器

[复制链接]
falaso 发表于 2017-12-30 16:16:41 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
学习装饰器首先要了解内嵌函数和闭包+ Q7 D( m3 P1 o7 R0 z
内嵌函数
& D$ {( C- S$ o! k' m& S1 H9 Y+ B. m0 u& ]6 ?+ m& H. P$ Q
函数是一段代码的封装,为了提高代码的重用性和简洁代码,可以直接通过函数调用。而内嵌函数是为了提升代码的丰富性,提供更多的作用。说白了就是在函数内部重新定义一个函数。9 `  O6 E7 n: _6 r8 ?( S
$ @" i! [! _" R2 M. C8 i2 x' Y% A' |

/ _) e3 _2 s2 \* g. u4 Z9 H3 z; zf1内嵌函数f2( h$ B$ E: C& f/ N% T& @2 A1 [0 U
函数f2就是在f1里面定义的一个函数,调用f1的时候也会调用f2,所以会输出f1 running和f2running。
4 `0 ^! \( y8 q- j! m% w3 ]9 o5 Y
调用f1结果# A* _& T- v% s
闭包
% S1 h0 o, k! A3 j9 V9 b- d; \9 i

0 m) Z1 f" y8 k, Y
1 `4 k$ O+ f/ l5 R# X* r闭包其实和内嵌函数很像,只不过闭包是返回内嵌函数,而没有直接调用内嵌函数。还拿刚才的例子:8 l& H. S* H2 Z: T: [

  G3 ?  R+ w  j
+ m: H3 Y+ Q2 h& ]+ V( u( lf2就是一个闭包
4 p( I' j! m& u+ \调用f1的时候会打印f1 running并返回一个函数体
  n8 {$ m3 l* y2 z$ w% D$ P+ [4 B( C/ r! [. w% |; |
F返会的函数体其实就是f2& N% _0 B6 Z! e
在python中调用函数要在函数后面加括号,例如调用f1函数,就是f1(),不加括号只是返回函数体,我们用一个变量f来接收返回的函数体,然后调用f函数
1 t7 z( e; \: ]) S/ e9 u5 e
& H( `6 q; }4 L0 K; `; _! u打印f2函数的代码
/ A5 p6 J$ o( ]' P% ]2 H; ^了解了内嵌函数和闭包就不难理解装饰器了,其实我在学习的时候也被搞得很难受。# p% ]& @: j5 l1 T/ ^" }
装饰器(decorator)% G3 z6 t. O! _2 q5 S1 @& r

) d3 X% j0 a  a& U3 c$ W8 T6 r' T7 f3 G
装饰器的定义:装饰函数的参数是被装饰的函数对象,返回原函数对象装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。那么怎么为存在的对象添加额外的功能呢?就是通过一个闭包来实现的,在上面的例子中,通过闭包不仅实现了f1函数要实现的也实现了f2函数的内容。装饰器就是一个闭包。写一个简单的装饰器
" L$ |8 ^" o( f* J2 ^! d5 ?1 I1 Z7 m' h/ H' o, C! k9 t; j
装饰器
5 m: a6 I+ k( ^9 N: N  |这个装饰器实现的功能很简单(在不改变原函数的情况下) * }" w+ v) u& K- a! I6 t9 P
调用f3,把函数f当做参数传进f3
9 j+ O4 V- v" M9 _# b: D2 E) w, D3 \; \6 g
调用f3
$ K: i7 ^* R+ t6 A# k* @8 O首先运行函数f3,打印f3 running 并返回一个函数体,这个函数体其实就是f4,我们用一个变量temp接收返回的函数体/ M; q( a( `6 a% g
然后调用temp6 ?- W/ v: F5 C( m
2 P. Q1 o2 p9 k/ G$ |" o7 G
调用temp(5)2 d2 q& y7 h6 U9 a; R
调用temp(5)的时候首先执行f4函数里的代码块打印f4 running,接着返回到最开始的函数f,并把5传进去,运行f,打印f
! S/ r1 E" I; |/ p! ]2 _1 grunning,计算5*5的值并返回到f4得出结果26.
9 `+ [: e; [2 e  Q7 J/ ^
" `$ U7 n, ^& B! \1 G完整运行顺序
0 G9 \. ^; p; ^  e. Y! @而python中的装饰器就是用一个@符号简化了
2 \0 v  B. H# Z$ a& c7 E/ O$ W/ z- p) ~  y& H1 o
@
+ F0 ]3 c& E  |. C这就是一个完整的装饰器,看上去很简洁,实现的效果是和刚才的代码一样的,我们来看看
, \! Y1 T, w* d; l& n) J! M# t: @
调用f(5)
+ x1 C7 p1 p# \4 K$ x& A3 }7 n# n/ D在这里装饰器是怎么工作的呢, F$ n+ L( @0 q: ?1 L8 |7 ~" Q
@f3就相当于 f = f3(f) 我们调用f函数看看会出现什么1 \& K. f, M) U9 }+ ]

7 a7 ~1 ?7 J' L% z1 W1 O( L' c& c: r8 q: j+ S* m
返回的是f4函数- Q$ m4 Z" N2 Y! V2 J
我们看看 调用f3(f)发生什么,
2 G" r. ~/ c) f. a5 ^6 A5 c0 f2 x5 B
函数一样
7 L7 h: W' s, n8 d7 N返回的也是函数f4,(函数地址不一样)就说明f = f3(f),之后的运行顺序和之前的一样,这里是我觉得比较难理解的地方。+ K! g4 J+ s5 A% O+ G1 C
由于本人水平有限,错误的地方欢迎指正。

本帖子中包含更多资源

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

x
回复

使用道具 举报

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

本版积分规则

发布主题
推荐阅读更多+
阅读排行更多+
用心服务创业者
0851-88611148
周一至周五 9:00-18:00
意见反馈:admin@0851life.com

扫一扫关注我们

Powered by 童码少儿编程 X3.4© 2001-2013 0851life Inc.|网站地图