闭包函数和装饰器
闭包函数
闭包函数的两大特征
- 闭:定义在函数内部的函数
- 包:内部函数使用了外层函数名称空间中的名字
def outer():
name = 'trump'
def inner ():
print("from inner function,", f'my name is {name}.')
return inner
name = 'obama'
res = outer()
res()
闭包函数实际应用
# 闭包函数是给函数体传参的另外一种方式,第一种用形参
def outer(username):
def index():
if username.isupper():
print(username)
else:
cap_name = username.upper()
print(cap_name)
return index
res = outer('trump')
res()
装饰器
-
装饰器的本质
在不改变被装饰对象原有的'调用方式'和'内部代码'的情况下给被装饰对象添加新的功能 -
装饰器的原则
- 对扩展开放
- 对修改封闭
- 应用
# 实际应用:统计函数的执行时间
import time
def index():
time.sleep(2.5)
print('from index')
start_time = time.time() # 函数执行之前获取一个时间戳
index()
end_time = time.time() # 函数执行之后获取一个时间戳
print(end_time - start_time) # 两个时间戳的差值就是函数的执行时间
简易版本装饰器
# 能够做到调用方式一致
import time
def delete():
time.sleep(1.5)
print('running delete')
print(delete)
def outer(func):
def get_time():
start_time = time.time() # 函数执行之前获取一个时间戳
func() # 执行被装饰的的delete函数
end_time = time.time() # 函数执行之后获取一个时间戳
print(end_time - start_time) # 两个时间戳的差值就是函数的执行时间
return get_time
delete = outer(delete) # 右边是一个普通变量名
delete() # running delete 1.5109477043151855
print(delete) # <function outer.<locals>.get_time at 0x0000020E388BE378>
进阶版本装饰器
# 解决的是参数问题
import time
def func_name(a):
time.sleep(2)
print(f'running {a} func')
def outer(func_name):
def get_time(*args, **kwargs):
start_time = time.time()
func_name(*args, **kwargs)
end_time = time.time()
print(end_time - start_time)
return get_time
res = outer(func_name)
res('delete')
完整版本装饰器
# 解决的是返回值问题
import time
def func_name(a):
time.sleep(1)
print(f'ruing {a} func')
def outer(func_name):
def get_time(*args, **kwargs):
start_time = time.time()
res = func_name(*args, **kwargs) # 执行被装饰的函数
end_time = time.time()
print(end_time - start_time)
return res
return get_time
func_name = outer(func_name)
func_name('modify')
装饰器模板
def func_mame():
print('from func')
return
def outer(func_name):
def inner(*args, **kwargs):
print('程序执行之前,可以添加的操作')
res = func_name(*args, **kwargs)
print('程序执行之后,可以添加的操作')
return res
return inner
func_name = outer(func_mame)
func_mame()
装饰器语法糖
def outer(func_name):
def inner(*args, **kwargs):
print('程序执行之前,可以添加的操作')
res = func_name(*args, **kwargs)
print('程序执行之后,可以添加的操作')
return res
return inner
@outer
def func_mame():
print('from func')
return
func_mame()
装饰器修复技术
from functools import wraps
def outer(func_name):
@wraps(func_name)
def inner(*args, **kwargs):
print('程序执行之前,可以添加的操作')
res = func_name(*args, **kwargs)
print('程序执行之后,可以添加的操作')
return res
return inner
@outer
def func_mame():
"""func用法"""
print('from func')
return
func_mame()
help(func_mame)