实现装饰器知识储
1.函数即‘变量'
2.高阶函数
(1)把一个函数名当做实参传给另外一个函数
def bar(x,y,f): print f(x)+f(y) bar(-1,-2,abs) >>3
def bar(): print '1111' print bar #输出内存地址 fun=bar #fun/bar指向内存中的同一地方 fun() >><function bar at 0x02249C30> >>1111
import time def bar(): time.sleep(3) print '1111' def f(fun): start_time=time.time() fun() stop_time=time.time() print '使用时间%s'%(stop_time-start_time) f(bar) >>1111 >>使用时间3.0
(2)返回值中包含函数名
3.嵌套函数
def foo(): print '1111' def bar(): #bar相当于局部变量,指定在定义域内调用,不能在外面调用 print '2222' bar() foo() >>1111 >>2222
x=0 def g(): def dad(): x=2 def son(): x=3 print x son() dad() g() >>3
高阶函数+嵌套函数=装饰器
import time def f(fun): def g(): start_time=time.time() fun() #这里的fun指向的是test1最初在内存中的地址,注意整个程序执行的顺序! print 'fun%s'%fun stop_time=time.time() print '时长%s'%(start_time-stop_time) print 'g%s'%g return g @f #test1=f(test1) #为test1添加装饰器 def test1(): #函数只有在被调用的时候才被定义(开辟内存空间)。 time.sleep(3) print '11111' print 'test1%s'%test1 test1() #这里的test1指向的是g函数存放的地址(位置) >>g<function g at 0x023081F0> >>test1<function g at 0x023081F0> >>11111 >>fun<function test1 at 0x02308170> >>时长-3.0
import time 可传参数的装饰器 name=2 def f(fun): def g(s): start_time=time.time() fun(s) #这里的fun指向的是test1最初在内存中的地址,注意整个程序执行的顺序! print 'fun%s'%fun stop_time=time.time() print '时长%s'%(start_time-stop_time) print 'g%s'%g return g @f #test1=f(test1) def test1(name): #函数在内存中被定义,调用该函数时,会开辟一个栈空间,来运行。 time.sleep(3) print '11111' print 'test1%s'%test1 test1('hh') #这里的test1指向的是g函数存放的地址(位置) >>g<function g at 0x034C8D30> >>test1<function g at 0x034C8D30> >>11111 >>fun<function test1 at 0x02A809B0> >>时长-130.470999956
import time 通用(无论有无参数)装饰器 name=2 def f(fun): def g(*a,**b): start_time=time.time() fun(*a,**b) #这里的fun指向的是test1最初在内存中的地址,注意整个程序执行的顺序! print 'fun%s'%fun stop_time=time.time() print '时长%s'%(start_time-stop_time) print 'g%s'%g return g @f #test1=f(test1) def test1(name,age): #函数在内存中被定义,调用该函数时,会开辟一个栈空间,来运行。 time.sleep(3) print '11111' print 'test1%s'%test1 test1('hh',23) #这里的test1指向的是g函数存放的地址(位置) >>g<function g at 0x022281F0> >>test1<function g at 0x022281F0> >>11111 >>fun<function test1 at 0x02228170> >>时长-3.00100016594
关于函数的命名空间如下:
当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心。
等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量会存储在新开辟出来的内存中。函数中的变量只能在函数的内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。
具体见:https://blog.csdn.net/qd_ltf/article/details/79698474
装饰器终极实例:
通过装饰器实现用户登录接口
name,pas='xx','qaz123' #被装饰函数有返回值的实例,需要返回调用函数的值f给所在定义函数调用时的输出print里 def f(fun): def g(*a,**b): user_name=raw_input('username:').strip() user_pass=raw_input('userpass:').strip() if name==user_name and pas==user_pass: print '输入正确!' f=fun('1','2') #fun函数在定义g函数里面调用,'1','2'传给def home(n,m)里面。
return f else: print '用户名或密码错误' return g @f def home(n,m): print 'welcome to home page' return n print home(1,2) #这里的home指向的是g函数所在的内存地址,这里面的实参传给def g(*a,**b)里面的形参。 >>username:xx >>userpass:qaz123 >>输入正确! >>welcome to home page >>1
name,pas='xx','qaz123' #细化上一实例,实现不同用户或不同页面的登陆(方式) def f(t): print '%s进入f'%t def k(fun): def g(*a,**b): if t=='xiaohong': user_name=raw_input('username:').strip() user_pass=raw_input('userpass:').strip() if name==user_name and pas==user_pass: print '输入正确!' f=fun('1','2') #fun函数在定义g函数里面调用,'1','2'传给def home(n,m)里面。 return 'xh正确' #每一个判断条件里面写return是因为,需要返回给当前定义函数的调用位置上。 else: print '用户名或密码错误' return 'xiaohong输入错误' elif t=='xiaoming': #if...elif.. if后面为true是将不再判断elif print 'xiaoming不会..' return 'xm走完' return g return k @f(t='xiaohong') def updat(n,m): print 'welcome to home page' return n @f(t='xiaoming') def home(n,m): print 'welcome to home page' return n print updat(1,2) print home(1,2) #这里的home指向的是g函数所在的内存地址,这里面的实参传给def g(*a,**b)里面的形参。 >>xiaohong进入f >>xiaoming进入f >>username:xx >>userpass:qaz123 >>用户名或密码错误 >>xiaohong输入错误 >>xiaoming不会.. >>xm走完
python 装饰器:
定义:本质是函数(装饰其他函数)就是为其他函数添加附加功能。
原则:1.不能修改被装饰的函数的源代码。
2.不能修改被装饰的函数的调用方式。
del 删除变量,删除的是内存中的门牌号(变量名),不是变量指向的值,del删除变量后,内存发现没有变量指向该值,该值也将被删除。
函数就是一种变量。