函数装饰器

函数装饰器

不想修改函数的调用方式 但是还想在原来的函数前后添加功能。

import time
def outer(f):    #装饰器函数
    def inner(*args,**kwargs):  
        start = time.time()      # 要装饰的部分
        ret = f(*args,**kwargs)  #f(1,2)       #被装饰的函数
        end = time.time()       # 要装饰的部分
        print(end - start)
        return ret+" 元旦好"
    return inner

@outer         #语法糖 @装饰器函数名    func=outer(func)
def func(a,b):     #被装饰的函数
    time.sleep(0.01)
    print('老板好同事好大家好',a,b)
    return '新年好'
l=func(1,2)
print(l)


老板好同事好大家好 1 2
0.02500128746032715
新年好 元旦好


 wrap版装饰器

from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方       他的作用是用来修复注释,如果不加@wrap则注释内容会被自动删除
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

带参数的装饰器

def d(a=None):  # 定义一个外层函数,给装饰器传参数--role
    def foo(func):  # foo是我们原来的装饰器函数,func是被装饰的函数
        def bar(*args, **kwargs):  # args和kwargs是被装饰器函数的参数
            # 根据装饰器的参数做一些逻辑判断
            if a:
                print("hello world")
            else:
                print("欢迎来到首页。")
            # 调用被装饰的函数,接收参数args和kwargs
            func(*args, **kwargs)
        return bar
    return foo


@d()  # 不给装饰器传参数,使用默认的'None'参数
def func1(name):
    print("Hello {}.".format(name))


@d("哈哈")  # 给装饰器传一个'哈哈'参数
def func2(name):
    print("Hello {}.".format(name))

if __name__ == '__main__':
    func1("Andy")
    func2("Andy")


欢迎来到首页。
Hello Andy.
hello world
Hello Andy.

 

装饰器的开发原则 

开放封闭原则 

开放 : 对装饰函数的扩展是开放的

封闭 : 对被装饰的函数的修改是封闭的  

 

多个装饰器装饰一个函数

def wrapper1(func):
    def inner1():
        print('wrapper1 ,before func')
        ret = func()
        print('wrapper1 ,after func')
        return ret
    return inner1

def wrapper2(func):
    def inner2():
        print('wrapper2 ,before func')
        ret = func()
        print('wrapper2 ,after func')
        return ret
    return inner2

def wrapper3(func):
    def inner3():
        print('wrapper3 ,before func')
        ret = func()
        print('wrapper3 ,after func')
        return ret
    return inner3

@wrapper3
@wrapper2
@wrapper1
def f():
    print('cat')
    return '哈哈哈'

print(f())        
结果显示
wrapper3 ,before func
wrapper2 ,before func
wrapper1 ,before func
cat
wrapper1 ,after func
wrapper2 ,after func
wrapper3 ,after func
哈哈哈
#多个装饰器对一个函数进行装饰,结果类似于俄罗斯套娃,语法糖在前先被调用的的在套娃的最外层,依次往里。


# def wahaha():
# '''
# 一个打印娃哈哈的函数
# :return:
# '''
# print('娃哈哈')
#
# print(wahaha.__name__) #查看字符串格式的函数名
# print(wahaha.__doc__) #查看注释
 
posted @ 2017-12-28 18:33  排骨南  阅读(168)  评论(0编辑  收藏  举报