在介绍装饰器前,首先要了解一下函数的嵌套
嵌套调用
在一个函数中调用另一个函数,从下面的例子中可以看到,my_max4函数调用的my_max2函数,并且将局部变量传给my_max2函数,很好理解
# 返回最大值 def my_max2(x,y): if x > y: return x else: return y def my_max4(a,b,c,d): res1 = my_max2(a,b) res2 = my_max2(res1,c) res3 = my_max2(res2,d) return res3 print(my_max4(1,20,-1,5))
换一种嵌套方式
#嵌套定义
x = 1 def f1(): print(‘in the f1‘) def f2(): print(‘in the f2‘) def f3(): print(‘in the f3‘) print(x) return f3 return f2 f = f1()
ff = f() ff() #返回结果 in the f1 in the f2
in the f3
1
这个不太好理解,从代码上看就是一个函数嵌套另一个函数,这样一层一层的嵌套。下面我们来拆分一下
1、我们可以看到f = f1()的时候,实际上是执行了f1这个函数(函数名后面加小括号,表示执行这个函数)
2、f1这个函数的功能是定义一个函数f2,并且return这个f2,
3、f1()执行后的结果就是返回f2这个函数,但不执行他,那么f实际上就是f2
4、因此当执行f()时,就是在执行f2(),而f2这个函数的功能是定义一个f3的函数,并返回f3,并没有执行f3,那么ff就相当于f3。
5、此时再执行ff(),就是在执行f3()这个函数里面的代码,所以最后的结果就是先打印‘in the f1‘,再打印‘in the f2‘,再打印‘in the f3‘,最后打印x的值1
闭包函数
从闭包函数的代码中我们可以发现,跟上面的函数嵌套是一样的。其实上面的函数就是一个闭包函数。
一句话概括闭包函数:函数内在包含子函数,并最终return子函数。
那么闭包函数有什么作用呢?
1、首先,闭包函数实现了将不同函数作用于中的的局部变量传到另一个函数中
2、其次,可以让函数外部代码调用函数内部的函数
3、最后,实现了面向对象的封装性,更安全更可靠
#f2为闭包函数 def f1(): x = 1 def f2(): print(x) return f2 f = f1()
装饰器
装饰器在遵循下面两个原则的前提下为被修饰者添加新功能
必须遵循两个原则:
1、一定不能修改源代码
2、不能修改调用方式
装饰器的格式是@xxx,装饰器本身其实就是一个函数,参数可有可无。
将@xxx加在函数的上面一行即可,例如:
@deco1 ====> test = deco1(test)
def test(): pass
如果有多个装饰器,向上叠加即可,执行顺序是从下往上执行
@deco3 @deco2 @deco1 #func1=deco1(index) -->func2=deco2(func1) -->index=deco3(func2) ===>index=deco3(deco2(deco1(index)))
下面的代码显示出装饰器和函数之间的执行顺序
1、在index函数上面加上装饰器timer,等价于index=timer(index),此时index相当于wrapper,timer中的形参func为index
2、执行index()相当于执行wrapper():
a、获取时间戳
b、执行原始的index函数(打印‘in the index‘)
c、获取时间戳
d、打印执行时间
3、在home函数上面加上装饰器timer,等价于home=timer(home),此时home相当于wrapper,timer中的形参func为home
4、执行home(‘tom‘,msg=‘xxx‘)相当于执行wrapper(*args,**kwargs):
a、获取时间戳
b、执行原始的home函数(打印‘in the home tom xxx‘),返回1
c、获取时间戳
d、打印执行时间
5、将返回值1赋值给res
6、打印res
def timer(func): def wrapper(*args,**kwargs): start_time=time.time() res = func(*args,**kwargs) #运行最原始的index stop_time=time.time() print("run time is %s" %(stop_time-start_time)) return res return wrapper @timer #index=timer(index) def index(): print(‘in the index‘) index() @timer def home(user,msg): print(‘in the home %s %s‘ %(user,msg)) return 1 res=home(‘tom‘,msg=‘xxxx‘) print(res)
------------------------------------------------------------------------------------------------------------ # 执行结果 in the index run time is 2.47955322265625e-05 in the home tom xxxx run time is 1.1205673217773438e-05 1
原文:http://www.cnblogs.com/wescker/p/6475693.html