本文实例讲述了Python装饰器原理与用法。分享给大家供大家参考,具体如下:
1、装饰器的本质是函数,主要用来装饰其他函数,也就是为其他函数添加附加功能
2、装饰器的原则:
(1) 装饰器不能修改被装饰的函数的源代码
(2) 装饰器不能修改被装饰的函数的调用方式
3、实现装饰器的知识储备
(1) Python中函数即‘变量'
a、变量在Python中的存储
1
2
|
x = 'Tomwenxing'
y = x
|
[说明]:
当Python解释器遇到语句x='Tomwenxing'时,它主要完成了两样工作:
1.在内存中开辟了一片空间用来存储字符串‘Tomwenxing'
2.在内存从创建了一个名为x的变量,并用它指向字符串‘Tomwenxing'所占据的内存空间(可以理解为房间和房间号的关系)
而语句y=x意为将变量x对字符串的引用赋值给变量y,即在内存中创建一个变量y,并使其指向变量x所指向的内存空间
b、函数在Python中的存储
1
2
|
def test():
pass
|
[说明]:
在Python中,函数的存储和变量相似,以上面的函数为例,Python解释其主要做两件事:
1.在内存中开辟一个内存空间,用来存储函数代码的字符串(本例中代码只有一句:pass)
2.在内存中创建一个变量test,用来指向存储函数代码字符串的内存空间(相当于test=‘函数体')
因此说在Python中函数即变量
(2) 高阶函数(下面两个条件满足任何一个即为高阶函数)
a、把一个函数名当做实参传递给另外一个函数
[对装饰器的影响]:达到“在不修改被装饰函数源代码的情况下为其添加功能”的效果
1
2
3
4
5
6
7
8
9
10
|
import time
def bar():
time.sleep( 2 )
print ( 'in the bar' )
def test(func):
start_time = time.time()
func()
stop_time = time.time()
print ( '函数的运行时间为:' ,stop_time - start_time)
test(bar)
|
运行结果:
in the bar
函数的运行时间为: 2.0021145343780518
b、返回值中包含函数名
[对装饰器的影响]:达到“不改变函数的调用方式“的效果
1
2
3
4
5
6
7
8
9
|
import time
def bar():
time.sleep( 3 )
print ( 'in the bar' )
def test2(func):
print ( '新添加的功能' )
return func
bar = test2(bar)
bar()
|
运行结果:
新添加的功能
in the bar
(3) 嵌套函数:在一个函数体内用def去声明一个新的函数(不是调用)
1
2
3
4
5
6
|
def foo():
print ( 'in the foo' )
def bar(): #声明一个新的函数,而不是调用函数
print ( 'in the bar' )
bar()
foo()
|
运行结果:
in the foo
in the bar
4、装饰器的语法:高阶函数+嵌套函数=》装饰器 (下面的例子可以用pycharm的调试器调试一下,看看代码的运行顺序)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import time
def timer(func):
def deco( * args, * * kwargs): #使用了不定参数
start_time = time.time()
res = func( * args, * * kwargs) #运行函数
stop_time = time.time()
print ( '运行时间:' ,stop_time - start_time)
return res # 若无返回值,则返回None
return deco
@timer #等价于test1=timer(test1)=deco,即test1()=deco()
def test1():
time.sleep( 3 )
print ( 'in the test1' )
@timer #等价于test2=timer(test2)=deco,即test2(name)=deco(name)
def test2(name):
time.sleep( 3 )
print ( 'in the test2' ,name)
test1()
print ( '-------------分界线------------------------' )
test2( 'Tomwenxing' )
|
运行结果:
in the test1
运行时间: 3.0001718997955322
-------------分界线------------------------
in the test2 Tomwenxing
运行时间: 3.000171422958374
5、带参数的装饰器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
# -*- coding:utf-8 -*-
user,passwd = 'Tomwenxing' , '123'
#如装饰器带参数,一般是三层嵌套
def auth(auth_type): #第一层的参数是装饰器的参数
def outer_wrapper(func): #第二层的参数是装饰器要装饰的目标函数
def wrapper( * args, * * kwargs): #第三次的参数是目标函数的参数
if auth_type = = 'local' :
username = input ( 'Username:' ).strip()
password = input ( 'Password:' ).strip()
if user = = username and passwd = = password:
print ( '用户Tomwenxing已经成功登录!' )
res = func( * args, * * kwargs) #运行目标函数
return res
else :
exit( '用户名或密码有错误' )
elif auth_type = = 'ldap' :
print ( '暂不支持这种登录方式!' )
return wrapper
return outer_wrapper
def index():
print ( '欢迎来到index页面' )
@auth (auth_type = 'local' ) #home=wrapper()
def home(name):
print ( '%s,欢迎来到home页面' % name)
return 'This is home page'
@auth (auth_type = 'ldap' )
def bbs():
print ( '欢迎来到bbs页面 ' )
index()
print ( '----------------------分界线-------------------' )
print ( '函数的返回值为:' ,home( 'wenxing' ))
print ( '----------------------分界线-------------------' )
bbs()
|
运行结果:
欢迎来到index页面
----------------------分界线-------------------
Username:Tomwenxing
Password:123
用户Tomwenxing已经成功登录!
wenxing,欢迎来到home页面
函数的返回值为: This is home page
----------------------分界线-------------------
暂不支持这种登录方式!
希望本文所述对大家Python程序设计有所帮助。
原文链接:http://www.cnblogs.com/duwenxing/p/7385438.html