装饰器一

装饰器

什么是装饰器

首先我们要明确 装饰器是一个函数,应该是叫做装饰器函数,简称为装饰器,这个函数遵守开闭原则,在不修改原函数的基础上对该函数进行功能的扩展

装饰器的作用

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

主要功能

在不改变函数调用方式的基础上在函数的前、后添加功能

装饰器的形成过程

有一个需求:计算一个已有的函数的运行时间。

(time模块,用于操作时间,下面用到的time.time是获取当前时间戳,这个时间戳是从1970年1月1日0点0分开始计算到现在的秒数。time.sleep() 程序暂停多少秒)

import time

def func1():
    print('in func1')
    time.sleep(1)

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')

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

func1('aaaaaa','bbbbbb')
print(func2('aaaaaa'))
带返回值的装饰器
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','bbbbbb')
print(func2('aaaaaa'))

装饰器的固定格式:

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

装饰器-进阶版

嵌套装饰器
import time

def wrapper(*args):
    def inner(f):
        print('inner', args)
        def inner2(*args,**kwargs):
            print('inner2',args)
            ret = f(*args,**kwargs) # ret = func(args,kwargs)
            return ret
        return inner2
    return inner



@wrapper(input('<<')) # func = wrapper(input)(func)  func = inner2
def func(a,b):
    time.sleep(0.1)
    print(a,b)
    return 111

func(5,6)       # inner2(5,6)
多个装饰器装饰一个函数
def wrapper1(func):
    def inner(a):
        print('wrapper1 ,before func',a)
        func(1)
        # print(id(func))
        print('wrapper1 ,after func',a)
    return inner

def wrapper2(func):
    def inner(a):
        print('wrapper2 ,before func',a)
        func(2)
        # print(id(func))
        print('wrapper2 ,after func',a)
    return inner

@wrapper2 # f = wrapper2(f   f = inner
@wrapper1 # f = wrapper1(f   f = inner
def f(a):
    print('in f',a)

f(1)

开闭原则

 1.对扩展是开放的

    为什么要对扩展开放呢?

    我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

  2.对修改是封闭的

    为什么要对修改封闭呢?

    就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

装饰器完美的遵循了这个开放封闭原则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值