Python:装饰器的简单理解

1、装饰器的本质是函数,主要用来装饰其他函数,也就是为其他函数添加附加功能

2、装饰器的原则:

(1) 装饰器不能修改被装饰的函数的源代码

(2) 装饰器不能修改被装饰的函数的调用方式

3、实现装饰器的知识储备

(1) Python中函数即‘变量’

a、变量在Python中的存储
1 x='Tomwenxing'
2 y=x

[说明]:

当Python解释器遇到语句x='Tomwenxing'时,它主要完成了两样工作:

  1.在内存中开辟了一片空间用来存储字符串‘Tomwenxing’

  2.在内存从创建了一个名为x的变量,并用它指向字符串‘Tomwenxing’所占据的内存空间(可以理解为房间和房间号的关系)

而语句y=x意为将变量x对字符串的引用赋值给变量y,即在内存中创建一个变量y,并使其指向变量x所指向的内存空间

b、函数在Python中的存储
1 def test():
2     pass

[说明]:

在Python中,函数的存储和变量相似,以上面的函数为例,Python解释其主要做两件事

  1.在内存中开辟一个内存空间,用来存储函数代码的字符串(本例中代码只有一句:pass)

  2.在内存中创建一个变量test,用来指向存储函数代码字符串的内存空间(相当于test=‘函数体’)

因此说在Python中函数即变量

(2) 高阶函数(下面两个条件满足任何一个即为高阶函数)

a、把一个函数名当做实参传递给另外一个函数

[对装饰器的影响]:达到“在不修改被装饰函数源代码的情况下为其添加功能”的效果

 1 import time
 2 def bar():
 3     time.sleep(2)
 4     print('in the bar')
 5 
 6 def test(func):
 7     start_time=time.time()
 8     func()
 9     stop_time=time.time()
10     print('函数的运行时间为:',stop_time-start_time)
11 
12 test(bar)

b、返回值中包含函数名

[对装饰器的影响]:达到“不改变函数的调用方式“的效果

 1 import time
 2 def bar():
 3     time.sleep(3)
 4     print('in the bar')
 5 
 6 def test2(func):
 7     print('新添加的功能')
 8     return func
 9 
10 bar=test2(bar)
11 bar()

(3) 嵌套函数:在一个函数体内用def去声明一个新的函数(不是调用)

1 def foo():
2     print('in the foo')
3     def bar(): #声明一个新的函数,而不是调用函数
4         print('in the bar')
5     bar()
6 
7 foo()

4、装饰器的语法:高阶函数+嵌套函数=》装饰器 (下面的例子可以用pycharm的调试器调试一下,看看代码的运行顺序)

 1 import time
 2 def timer(func):
 3     def deco(*args,**kwargs):#使用了不定参数
 4         start_time=time.time()
 5         res=func(*args,**kwargs) #运行函数
 6         stop_time=time.time()
 7         print('运行时间:',stop_time-start_time)
 8         return res  # 若无返回值,则返回None
 9     return deco
10 
11 @timer #等价于test1=timer(test1)=deco,即test1()=deco()
12 def test1():
13     time.sleep(3)
14     print('in the test1')
15 
16 @timer #等价于test2=timer(test2)=deco,即test2(name)=deco(name)
17 def test2(name):
18    time.sleep(3)
19    print('in the test2',name)
20 
21 test1()
22 print('-------------分界线------------------------')
23 test2('Tomwenxing')

5、带参数的装饰器

 1 user,passwd='Tomwenxing','123'
 2 #如装饰器带参数,一般是三层嵌套
 3 def auth(auth_type): #第一层的参数是装饰器的参数
 4     def outer_wrapper(func):#第二层的参数是装饰器要装饰的目标函数
 5         def wrapper(*args,**kwargs):#第三次的参数是目标函数的参数
 6            if auth_type=='local':
 7                username = input('Username:').strip()
 8                password = input('Password:').strip()
 9                if user == username and passwd == password:
10                    print('用户Tomwenxing已经成功登录!')
11                    res = func(*args, **kwargs) #运行目标函数
12                    return res
13                else:
14                    exit('用户名或密码有错误')
15            elif auth_type=='ldap':
16                print('暂不支持这种登录方式!')
17         return wrapper
18     return outer_wrapper
19 
20 def index():
21     print('欢迎来到index页面')
22 
23 @auth(auth_type='local') #home=wrapper()
24 def home(name):
25     print('%s,欢迎来到home页面' %name)
26     return 'This is home page'
27 
28 @auth(auth_type='ldap')
29 def bbs():
30     print('欢迎来到bbs页面 ')
31 
32 
33 index()
34 print('----------------------分界线-------------------')
35 print('函数的返回值为:',home('wenxing'))
36 print('----------------------分界线-------------------')
37 bbs()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值