python 装饰器
实现装饰器知识储
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删除变量后,内存发现没有变量指向该值,该值也将被删除。
函数就是一种变量。
本博客只记录个人的学习过程,如对文中有不懂的地方,可以在评论区留言!

浙公网安备 33010602011771号