python装饰器

装饰器

装饰器的本质:一个闭包函数

装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

import time

def func1():
    print('in func1')

def timer(func):   # 装饰器函数
    def inner():
        start = time.time()
        func()    # 被装饰的函数
        print(time.time() - start)
    return inner

func1 = timer(func1)
func1()

#-----------------------------------------------------------
# 语法糖
import time
def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

@timer   #==> func1 = timer(func1)
def func1():
    print('in func1')


func1()

装饰器——带参数的装饰器

def timer(func):
    def inner(a):
        start = time.time()
        func(a)
        print(time.time() - start)
    return inner

@timer
def func1(a):
    print(a)

func1(1)

装饰器——成功hold住所有函数传参

import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func1 = timer(func1)
def func1(a,b):
    print('in func1')

func1('aaaaaa','bbbbbb')

装饰器——带返回值的装饰器

import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func2 = timer(func2)
def func2(a):
    print('in func2 and get a:%s'%(a))
    return 'fun2 over'

func2('aaaaaa')
print(func2('aaaaaa')

查看函数信息的一些方法

def index():
    '''这是一个主页信息'''
    print('from index')

print(index.__doc__)    #查看函数注释的方法
print(index.__name__)   #查看函数名的方法

完美的装饰器

from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

@deco
def index():
    '''哈哈哈哈'''
    print('from index')

print(index.__doc__)
print(index.__name__)

装饰器固定模式

def wrapper(func):
    def inner(*args,**kwargs):
         '''写函数之前要做的'''
        ret = func(*args,**kwargs)
        '''写函数之后要做的'''
        return ret
    return inner

@wrapper
def func(*args):
    print(args)
    return 'func over'
    
ret = fuc()
        

开放封闭原则

  • 对扩展是开放的
  • 对修改是封闭的
def warrper(func):
    def inner(*args,**kwargs):
        print('在被装饰器函数执行之前要做的事')
        ret = func(*args,**kwargs)
        print('在被装饰器函数执行之后要做的事')
        return ret
    return inner

@warrper  # 等于 holiday = warrper(holiday)
def holiday(day):
    print('全体放假%s天' %day)
    return '好开心'

ret = holiday(3)  # 等于inner(3)
print(ret)

带参数的装饰器

def outer(flag):
    def timer(func):
        def inner(*args,**kwargs):
            if flag:
                print('''执行函数之前要做的''')
            re = func(*args,**kwargs)
            if flag:
                print('''执行函数之后要做的''')
            return re
        return inner
    return timer

@outer(False)
def func():
    print(111)

func()
import time
FLAG = 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)
            	return ret
            else:
                ret = func(*args,**kwargs)
                return ret        
        return inner
    return timmer

@timmer_out(FLAG)  # 等于@timmer  timmer = timmer_out(FLAG)
def wahaha():
    time.sleep(1)
    print('hahahahaha')
    
wahaha()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cTPaA6Ai-1582092534098)(D:\学习笔记\九月\1568686641493.png)]

多个装饰器装饰同一个函数

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

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

@wrapper2  # f = wrapper2(inner1) = inner2
@wrapper1  # f = wrapper1(f) = inner1
def f():
    print('in f')

f()

# 执行结果

>>> wrapper2 ,before func
>>> wrapper1 ,before func
>>> in f
>>> wrapper1 ,after func
>>> wrapper2 ,after func

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值