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)归纳完毕,下周总结后半部分相关内容,下周见~