python学习-第十六周:装饰器(1)

python学习-第十六周:装饰器(1)

什么是装饰器?

在不改变原有函数代码,且保持原函数调用方法不变的情况下,给原函数增加新的功能(或者给类增加属性和方法)
核心思想:用一个函数(或者类)去装饰一个旧函数(或者类),造出一个新函数(或者新类)
应用场景:引入日志,函数执行时间的统计,执行函数前的准备工作,执行函数后的处理工作,权限校验,缓存等
语法规则:在原有的函数上加上 @ 符,装饰器会把下面的函数当作参数传递到装饰器中,@ 符又被成为 语法糖

1.装饰器原型

利用闭包,把函数当作参数传递,并且在函数内去调用传递进来的函数,并返回一个函数

# 定义外函数,接收一个函数作为参数
def outer(f):
    # 定义内函数,并且在内函数中调用了外函数的参数
    def inner():
        print('参数函数执行前')
        f()
        print('参数函数执行后')
    # 将内函数返回
    return inner

# 改为装饰器用法
@outer      # 此处使用的@outer的语法就是把outer作为了装饰器,等同于 old = outer(old)
def old():
    print('我是一个普通的函数')

old()  # old函数经过 outer装饰器进行了装饰,代码和调用方法不变,但是函数的功能发送了改变
'''
参数函数执行前
我是一个普通的函数
参数函数执行后
'''

2.装饰器的应用:统计函数的执行时间

# 装饰器应用场景-统计函数执行时间
import time
# 定义一个统计函数执行时间的 装饰器
def runtime(f):
    def inner():
        print('计时开始')
        start = time.perf_counter()
        f()
        end =  time.perf_counter() - start
        print('计时结束')
        print(f'函数的调用执行时间为:{end}')
    return inner

# 定义一个函数
@runtime
def func():
    for i in range(5):
        print(i)
        time.sleep(1)
# 执行函数
func()
'''
计时开始
0
1
2
3
4
计时结束
函数的调用执行时间为:5.0484206
'''

3.装饰器嵌套语法

# 1.定义装饰器
def outer(func):
    def inner():
        print('内部3')
        func()  
        print('内部4')
    return inner

# 2.定义另一个装饰器
def kuozhan(f):
    def kz():
        print('扩展1')
        f()
        print('扩展2')
    return kz

# 3. 装饰器的嵌套 由近到远执行。
@kuozhan 
@outer   
def func():
    print('5')

func()
''' 过程解析
1 先使用离得近的 outer装饰器 装饰func函数,返回了一个 inner函数
2 再使用上面的 kuozhan 装饰器,装饰 上一次返回的 inner 函数,又返回了 kz 函数

func函数的输出顺序
    func() ==> kz()
                ===>  扩展1
                ===>  inner()  
                           ===> 内部3
                           ===> func() ===> 5
                           ===> 内部4
                ===>  扩展2
'''

4.对带有参数的函数进行装饰

# 定义装饰器
def outer(func):
    # 如果装饰器带有参数的函数,需要在内函数中定义行参,并传递给调用的函数。因为调用原函数等于调用内函数
    def inner(var):
        print('打开冰箱门!')
        func(var)
        print('关闭冰箱门!')
    return inner

# 有参数的函数
@outer
def func(animal):
    print(f'把{animal}装进冰箱!')

func('大象') #func() ==> inner()   func('大象') ===> inner('大象')
'''
打开冰箱门!
把大象装进冰箱!
关闭冰箱门!
'''

装饰器(1)归纳完毕,下周总结后半部分相关内容,下周见~

上一篇:python中函数嵌套、函数作为变量以及闭包的原理


下一篇:pandas的读书报告: