Python3-装饰器 装饰器

装饰器(语法糖)

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

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

例子1.

给hahaha函数加上一个timmer(计算函数执行时间)的功能。

import time
def timmer(func):
    #函数名可以当做函数的参数
    def inner():
        start = time.time()
        func()
        end = time.time()
        print(start - end)
    return inner

# 语法糖
@timmer       # @把hahaha函数名作为参数传到timmer(),执行了一次, 然后进行了重新赋值 hahaha = timmer(hahaha) --> inner()
def hahaha():
    time.sleep(0.1)
    print('aaaa')

# time(hahaha)      不能改变这个函数的调用方式
# 也不能修改源代码
# hahaha = timmer(hahaha)       timmer(hahaha)函数的执行结果返回 inner函数的内存地址,然后赋值给hahaha
# hahaha()  就等同于  inner()

hahaha()

装饰器的设计模式:开放封闭原则

开放:对扩展是开放的

封闭:对修改是封闭的

刚刚我们讨论的装饰器都是装饰不带参数的函数,现在要装饰一个带参数的函数怎么办?

import time

def timer(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)
        end_time = time.time()
        print(end_time - start_time)
    return inner

@timer
def func1(a):
    time.sleep(2)
    print(a)

func1('bb')

带参数的装饰器

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

@outer(True)
def func2(mode):
    print(111, mode)

func2('rrr')

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

有些时候,我们也会用到多个装饰器装饰同一个函数的情况。

def wrapper1(func):
    def inner():
        print('wrapper1 ,before func')
        func()
        print('wrapper1 ,after func')
    return inner

def wrapper2(func):
    def inner():
        print('wrapper2 ,before func')
        func()
        print('wrapper2 ,after func')
    return inner

@wrapper2
@wrapper1
def f():
    print('in f')

f()

输出:

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

猜你喜欢

转载自www.cnblogs.com/Xuuuuuu/p/10178392.html