python全栈-Day 11

一、装饰器的初成

1、一个需要做装饰器的示例

import time

def func():
    time.sleep(0.1)    #让程序暂停执行0.1s
    print('你好')

def timer(f):    #运行f函数,并计算f函数的执行时间----这样做要修改全部的函数名称为timer,非常消耗时间
    start = time.time()    #1533213779.934297,从1970到现在经过的秒数----获取当前的时间戳
    f()
    end = time.time()
    print(end - start)

timer(func)

2、使用装饰器的方法解决以上问题,好处是:只要  func1 = timer(func1)  赋值不同函数,就可以实现计算多个函数的执行时间的功能

  • 不需要修改函数的调用方式,但是可以在已有的函数前后添加一些公共功能
  • timer就是一个装饰器函数,只是对一个函数,有装饰作用,被装饰的函数是f
import time
def func1():
    time.sleep(0.1)
    print('func1')

def timer(f):
    def inner():
        start = time.time()
        f()
        end = time.time()
        print(end - start)
    return inner

func1 = timer(func1)    #实际上func1指向了inner的内存地址
func1()    #执行inner函数

二、开放封闭原则

1、开放:对扩展是开放的

2、封闭:对修改是封闭的----如果修改了老的函数,可能影响之前已经使用该函数的功能,因此不允许修改

三、一个基础的装饰器的最终形成和固定格式

1、不完整的装饰器

不完整的装饰器:没有返回值
import time
def timer(f):    #装饰器函数
    def inner():
        start = time.time()
        f()
        end = time.time()
        print(end - start)
    return inner

@timer    #语法糖,@装饰器函数名。在被装饰函数上方紧贴着装饰器,相当于  func1 = timer(func1)
def func1():
    time.sleep(0.1)
    print('func1')
    return '你好呀'

print(func1())    #func1相当于inner,因此返回值是inner的返回值None,拿不到func1本身的返回值

2、完整的装饰器

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

@timer    #语法糖,@装饰器函数名。在被装饰函数上方紧贴着装饰器,相当于  func1 = timer(func1)
def func1():
    time.sleep(0.1)
    print('func1')
    return '你好呀'

print(func1())    #func1相当于inner,因此返回值是inner的返回值None,拿不到func1本身的返回值

3、注意,如果被装饰函数有参数,则 被装饰函数、装饰器函数、装饰器函数中调用的被装饰函数、执行被装饰函数 4个位置都需要加上参数

4、如果被装饰函数有多个参数,则需要遵循 形参、实参的规则(注意灵活使用 *args、**kwargs)

#完整的装饰器----多个被装饰参数,携带多个位置参数和关键字参数
import time
def timer(f):    #装饰器函数
    def inner(*args,**kwargs):    #*args、**kwargs作为形参,实现 多个元素-单个元组、字典 的操作
        start = time.time()
        ret = f(*args,**kwargs)    #*args、**kwargs作为实参,实现 单个元组、字典-打散到单个元素的操作
        end = time.time()
        print(end - start)
        return ret
    return inner

@timer
def func1(a):
    time.sleep(0.1)
    print('func1',a)
    return '你好呀'

@timer
def func2(a,b):
    time.sleep(0.1)
    print('func1',a,b)
    return '你好呀'

print(func1('func1-a'))
print(func2('func2-a','func2-b'))

5、装饰器的固定格式

import time
def wrapper(f):    #装饰器函数,f是被装饰的函数名----形参
    def inner(*args,**kwargs):
        '''在被装饰函数之前要做的事'''
        ret = f(*args,**kwargs)
        '''在被装饰函数之后要做的事'''
        return ret
    return inner

@wrapper    #语法糖,@装饰器函数名,等同于  func = wrapper(func),func被赋值为inner
def func(a,b):    #被装饰的函数
    time.sleep(0.1)
    print('func',a,b)
    return 'func结束啦'

print(func('ddfs',22))
原文地址:https://www.cnblogs.com/txbbkk/p/9409709.html