python--装饰器

为什么要有装饰器?

开放封闭原则:对修改封闭,对扩展开放

什么是装饰器?

  装饰器是可调用的函数,被装饰者也是可以调用的函数

  原则:不修改被装饰者的代码,不改变被装饰者的调用方式

  目的:给被装饰者添加功能

实现过程

 1 #原始index函数
 2 import time
 3 def index():
 4     time.sleep(3)
 5     print('贼溜')
 6     return '大牛'
 7 
 8 #为index函数添加功能
 9 strat_time = time.time()
10 index()
11 end_time = time.time()
12 print(end_time - strat_time)
13 
14 #上述添加过程在为其他函数添加功能时,需要重复写代码,改进如下
15 def wrapper():
16     strat_time = time.time()
17     index()
18     end_time = time.time()
19     print(end_time - strat_time)
20 wrapper()
21 
22 #上述改进过程,只能为index()添加功能,而且改变了index的调用方式,改进如下
23 def timmer(func):
24     def wrapper():
25         strat_time = time.time()
26         res=func()
27         end_time = time.time()
28         print(end_time - strat_time)
29         return res
30     return wrapper
31 index=timmer(index)   #闭包函数的概念---timmer(index)实际上就是调用了一个带有func=index参数的wrapper()
32 
33 #改进依然不完美,当传入的函数带有参数时,程序报错,改进如下
34 def timmer(func):
35     def wrapper(*args,**kwargs):
36         strat_time = time.time()
37         res=func(*args,**kwargs)
38         end_time = time.time()
39         print(end_time - strat_time)
40         return res
41     return wrapper
42 #至此,装饰器完成,得到如下模板
43 def outter(func):
44     def wrapper(*args,**kwargs):
45         res = func(*args,**kwargs)
46         return res
47     return wrapper
48 #任何装饰器都可以套用此模板

 

 

基本语法

@deco1
@deco2
@deco3
def foo():
    pass


foo =deco1(deco2(deco3(foo)))

foo()是需要被装饰的函数

 

无参装饰器

import time
def timmer(func):                                                      
    def wrapper(*args,**kwargs):      #wrapper()为闭包函数
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
        return res
    return wrapper                #timmer()的返回值指向函数wrapper()的内存地址

@timmer
def foo():
    time.sleep(3)
    print('from foo')
foo()

 

有参装饰器

def auth(driver='file'):#此处可以添加任意参数,所有有参装饰器最多三层即可
    def auth2(func):   #此处的func固定,不允许添加值,只能是被装饰函数的内存地址
        def wrapper(*args,**kwargs):#此处不允许修改,一旦修改,则程序在装饰有参函数和无参函数时,其中一个肯定报错
            name=input("user: ")
            pwd=input("pwd: ")

            if driver == 'file':#作用域知识,本层找不到,往外部找
                if name == 'egon' and pwd == '123':
                    print('login successful')
                    res=func(*args,**kwargs)
                    return res
            elif driver == 'ldap':
                print('ldap')
        return wrapper
    return auth2

@auth(driver='file')
def foo(name):
    print(name)
res = auth(driver='file')
print(res)
foo('egon')

 

posted @ 2018-03-29 14:50  木夂口  阅读(161)  评论(0编辑  收藏  举报
levels of contents