Python——装饰器

1. 装饰器

(1)最简单的装饰器

import time

def timmer(f):
    start = time.time()
    f()
    end = time.time()
    print(end-start)

def func():
    time.sleep(1)
    print('老板好')
timmer(func)

(2)有返回值的装饰器

import time
def timmer(f):  #装饰器函数
    def inner():
        start = time.time()
        ret = f() #被装饰的函数
        end = time.time()
        print(end-start)
        return ret
    return inner

@timmer     #语法糖:放在被装饰函数的前一行
def func():
    time.sleep(1)
    print('你好我好大家好')
    return '新年好'

# func = timmer(func)   有语法糖,可以不写此句话,同义

ret = func()    #inner()
print(ret) 

(3)带一个参数的装饰器

import time
def timmer(f):  #装饰器函数
    def inner(a):
        start = time.time()
        ret = f(a) #被装饰的函数
        end = time.time()
        print(end-start)
        return ret
    return inner

@timmer     #语法糖:放在被装饰的函数前一行
def func(a):
    time.sleep(1)
    print('你好我好大家好',a)
    return '新年好'
# func = timmer(func)   有语法糖,可以不写此句话,同义

ret = func(1)    #inner()
print(ret)

(4)带多个参数的装饰器

import time
def timmer(f):  #装饰器函数
    def inner(*args,**kwargs):
        start = time.time()
        ret = f(*args,**kwargs) #被装饰的函数
        end = time.time()
        print(end-start)
        return ret
    return inner

@timmer     #语法糖:放在被装饰的函数前一行
def func(a,c,d,b):
    time.sleep(1)
    print('你好我好大家好',a,c,d,b)
    return '新年好'

# func = timmer(func)   有语法糖,可以不写此句话,同义

# ret = func(1,2)    #inner()
# ret = func(1,b = 2)    #inner()
ret = func(1,3,4,b = 2)    #inner()
print(ret)

2. 装饰器的作用:

  不修改函数的调用方式,但是还想在原来的函数前后添加功能
  timmer就是一个装饰器函数,只是对一个函数有些装饰的作用

3. 开放封闭原则   

  开放:对扩展是开放的
  封闭:对修改时封闭的

4. 装饰器的固定模式

import time 

def wrapper(func):  # 装饰器函数,func = qqxing
    def inner(*args, **kwargs):
     #被装饰函数之前要做的
        ret = func(*args, **kwargs)  # func是被装饰的函数
     #被装饰函数之前要做的
        return ret
    return inner

@wrapper      # qqxing = wrapper(qqxing)
def qqxing():
    print(123)
ret = qqxing()  # inner
print(ret)

 5. 装饰器的进阶

(1)functools.wrap

from functools import wraps
def wrapper(func):#(1)
    @wraps(func)
    def inner(*args,**kwargs):#(4)
        print('在被装饰的函数执行之前做的事')
        ret = func(*args,**kwargs)#(8) holiday(*(3),**{}) #(12)ret接收返回值
        print('在被装饰的函数执行之后做的事')
        return ret#(14)
    return inner#(5)

@wrapper    #(6)赋值#holiday = wrapper(holiday)   #(2,3)
def holiday(day):
    '''这是一个放假通知'''
    print('中秋放假%s天'%day)#(10)
    return '好开心'#(11)
print(holiday.__name__) #inner(没有wraps)
print(holiday.__name__) #holiday(有wraps之后)
print(holiday.__doc__)

ret = holiday(3)    #(7)inner(3)    #(15)ret接收返回值
print(ret)#(16)

 运行结果:

(2)带参数的装饰器

import time
FLAGE = True
def timmer_out(flag):
    def timmer(func):
        def inner(*args, **kwargs):
            if flag:
                start = time.time()
                ret = func(*args, **kwargs)
                end = time.time()
                print(end - start)
            else:
                ret = func(*args, **kwargs)
                return ret
        return inner
    return timmer

@timmer_out(FLAGE)  #timmer = timmer_out(FLAGE)     @timmer
def wahaha():
    time.sleep(0.2)
    print('wahahahahahaha')

@timmer_out(FLAGE)
def erguotou():
    time.sleep(0.1)
    print('erguotoutoutou')

wahaha()
erguotou()

运行结果:

(3)多个装饰器装饰同一个函数

   <1>两层

def wrapper1(func):
    def inner1():#func-->f
        print('wrapper1,before func')
        func()  #f
        print('wrapper1,after func')
    return inner1
def wrapper2(func):#func-->inner1
    def inner2():
        print('wrapper2,before func')
        func()  #inner1
        print('wrapper2,after func')
    return inner2
@wrapper2   #f = wrapper2(f) = wrapper2(inner1) == inner2
@wrapper1   #f = wrapper1(f) = inner1

def f():
    print('in f')
f() #-->inner2()

  运行结果:

  <2>三层

def wrapper1(func):
    def inner1():
        print('wrapper1,before func')
        func()
        print('wrapper1,after func')
    return inner1
def wrapper2(func):
    def inner2():
        print('wrapper2,before func')
        func()
        print('wrapper2,after func')
    return inner2
def wrapper3(func):
    def inner3():
        print('wrapper3,before func')
        func()
        print('wrapper3,after func')
    return inner3
@wrapper3
@wrapper2
@wrapper1
def f():
    print('in f')
f()

  运行结果:

  <3>有返回值的完整的三层

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('in f')
    print('哈哈哈')
f()

  运行结果:

 

  <4>执行顺序:

 

posted @ 2018-09-19 09:44  xc_718  阅读(127)  评论(0编辑  收藏  举报