装饰器

 1.装饰器的原理及为什么要用装饰器

原理:闭包函数(内部函数包含了对外部函数作用域而非全局作用域的引用)

闭包的意义:返回的函数对象,不仅仅是一个函数对象,还自带了一层作用域,那么函数无论在那里调用,都会优先使用自己外层的作用域

为什么要用:

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

 2. 装饰器的基本用法

@....
def warpper(func):
    def inner(*args,**kwargs):
        return func(*args,**kwargs)
    return inner

 

 3. 带参数的装饰器

import time

def timmer(func):
    def wrapper(*args,**kwargs):
        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
def foo():
    time.sleep(3)
    print('from foo')
foo()
无参装饰器的简单应用
def auth(driver='file'):
    def auth2(func):
        def wrapper(*args,**kwargs):
            name = input('user: ')
            pwd = input('pwd: ')

            if driver == 'file':
                if name == 'guo' 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)

foo('guo')
有参装饰器的简单应用

 

 4. 被装饰的函数有返回值怎么处理

@....
def warpper(func):
    def inner(*args,**kwargs):
        res =  func(*args,**kwargs)
        return res
    return inner
被装饰函数有返回值

 

 5. 多个装饰器的执行顺序

一般来说,装饰器的执行顺序是自下而上的,但是真相并不是这么简单的!!!请看这里!!!!


 6. 装饰类的装饰器

主要是@property   @classmethod   @staticmethod   点击查看

 

7.关于wraps

Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。写一个decorator的时候,最好在实现之前加上functools的wrap,它能保留原有函数的名称和docstring。

#coding=utf-8  
# -*- coding=utf-8 -*-   
from functools import wraps     
def my_decorator(func):  
    def wrapper(*args, **kwargs):  
        '''''decorator'''  
        print('Calling decorated function...')  
        return func(*args, **kwargs)  
    return wrapper    
 
@my_decorator   
def example():  
    """Docstring"""   
    print('Called example function')  
print(example.__name__, example.__doc__)
不加wraps的时候

运行结果:

('wrapper', 'decorator')
[Finished in 0.2s]

#coding=utf-8  
# -*- coding=utf-8 -*-   
from functools import wraps     
def my_decorator(func):  
    @wraps(func)  
    def wrapper(*args, **kwargs):  
        '''''decorator'''  
        print('Calling decorated function...')  
        return func(*args, **kwargs)  
    return wrapper    
 
@my_decorator   
def example():  
    """Docstring"""   
    print('Called example function')  
print(example.__name__, example.__doc__)  

 运行结果:

('example', 'Docstring')
[Finished in 0.5s]

posted @ 2018-06-04 19:11  木夂口  阅读(94)  评论(0编辑  收藏  举报
levels of contents