【python3】 函数 装饰器

第一步 : 了解装饰器

  装饰器模式,重点在于装饰,装饰的核心仍是被装饰的对象。

  举一个栗子:我今天穿了一件短袖,但是突然一阵风,短袖没办法为我御寒,我想到的办法是将短袖变得更厚更长,但是改造之后,它就不是一件真正的短袖了。

      于是有了长袖的诞生,将长袖套在短袖外面,既可挡风又可御寒,妈妈再也不用担心我感冒了。短袖是短袖,长袖是长袖,相互独立。

      装饰器就像我们的长袖,在不影响短袖改造的情况下,达到了挡风御寒的效果。

  装饰器的应用场景:插入日志、性能测试、事务处理、缓存等。

第二步 : 定义一个基础函数(短袖)

def short_T():
    ## 定义一个基础函数
    print("穿了一件短袖")
    
short_T()

第三步:写一个测试函数执行时间的函数(长袖) 

import time

def long_T(func):
    ## 定义一个测试函数执行时间的函数(装饰函数)
    def inner():
        start_time = time.time()
        short_T
        poor = time.time() - start_time
        print("函数的执行时间为:%d s"%poor)
    return inner


def short_T():
    print("穿了一件短袖")

short_T = long_T(short_T())    ## =====>装饰器实质:装饰函数的参数是被装饰函数的对象()
short_T()

执行顺序:


1、python解释器开始执行后,引入time模块;

2、先读函数long_T,再读函数short_T(将函数名放在内存,但不执行);

3、执行调用者等号右边long_T(short_T),执行long_T函数,并将参数short_T传入函数;

4、读函数inner,将inner函数的返回值inner赋值给调用者short_T(则short = inner),执行inner()函数(则short_T = inner());

5、计算开始时间,(传入参数为:short_T,则func() = short_T()),执行short_T函数,打印“穿了一件函数”;

6、计算函数结束与开始时间的差值,并打印差值,函数执行完毕。

 第四步 : 使用语法糖(@)装饰函数(换一件好看的长袖)

'''
使用语法糖(@被装饰函数)来代替
short_T = long_T(short_T()
'''

import
time def long_T(func): ## 定义一个测试函数执行时间的函数 def inner(): start_time = time.time() func() poor = time.time() - start_time print("函数的执行时间为:%d s"%poor) return inner @long_T def short_T(): ## 定义一个基础函数 print("穿了一件短袖") short_T()

第五步 : 装饰器--hold住所有参数的装饰器

import time

def long_T(func):
    ## 定义一个测试函数执行时间的函数
    def inner(*args,**kwargs):              ## 添加万能参数
        start_time = time.time()
        func(*args,**kwargs)                ## 添加万能参数
        poor = time.time() - start_time
        print("函数的执行时间为:%d s"%poor)
    return inner

@long_T
def short_T(a,b):                           ## 无论传多少参数,装饰器都能接收
    ## 定义一个基础函数
    print("%s和%s穿了一件短袖"%(a,b))

short_T("小白","小黑")

第六步 : 装饰器--有返回值的装饰器

import time

def long_T(func):
    ## 定义一个测试函数执行时间的函数
    def inner(*args,**kwargs):
        start_time = time.time()
        ret = func(*args,**kwargs)             ## 接收返回的值
        poor = time.time() - start_time
        print("函数的执行时间为:%d s"%poor)
        return ret                  ## 返回接收的值给接收者
    return inner

@long_T
def short_T(a,b):
    ## 定义一个基础函数
    return("%s和%s穿了一件短袖"%(a,b))

print(short_T("小白","小黑"))            ## 打印返回的值

装饰器模板:

def wrapper(func):
    def inner(*args,**kwargs):
        ## 执行函数前操作
        ret = func(*args,**kwargs)
        ## 执行函数后操作
        return ret
    return inner

开放封闭原则

  1、对扩展是开放的:任何一个程序,做到完美,总是经过不断的迭代来升级更新,所有我们必须允许代码扩展,添加新功能;

  2、对修改的封闭的:其一,开发写的函数,有交付给其他人去使用,如果进行修改,很可能影响其他正在使用函数的用户;

             其二,在原有功能上修改函数,很有可能牵一发而动全身,引发其他部分的bug。

  装饰器遵循了开放封闭原则

 1) 获取装饰器函数的函数名和注释信息:

def wrapper(func):
    def inner(*args,**kwargs):
        '''执行函数前操作'''
        ret = func(*args,**kwargs)
        '''执行函数后操作'''
        return ret
    return inner

@wrapper
def f1():
    ''' 注释信息 '''
    print(f1.__name__)               ## 获取函数名
    print(f1.__doc__)                ## 获取函数注释信息

f1()       # ==== inner()

运行结果:

inner
执行函数前操作

2)获取被装饰器函数的函数名和注释信息:

from functools import wraps         ## 引入模块
def wrapper(func):
    @wraps(func)               ## 放在最内层函数正上方
    def inner(*args,**kwargs):
        '''执行前操作'''
        ret = func(*args,**kwargs)
        '''执行后操作'''
        return ret
    return inner

@wrapper
def name():
    '''注释信息'''
    print(name.__name__)
    print(name.__doc__)
name()


运行结果:

  name
  注释信息

猜你喜欢

转载自www.cnblogs.com/clamheart/p/10332835.html