一、闭包定义
闭包函数指在函数内部定义另一个函数,并且可以访问和修改函数外部的变量。是一种特殊的函数,是python中一种使用频率较高的编程技巧。闭包函数定义语法如下:
# 闭包函数
def t_func():
def t1_func():
print("执行闭包函数")
return t1_func
# 调用闭包函数
t = t_func()
print(type(t))
t()
# 运行结果
<class 'function'>
执行闭包函数
二、装饰器
1、装饰器定义
装饰器顾名思义,用于装饰对象(只能作用于函数)。可使被装饰对象在没有任何变动的情况下增加额外功能,其本质为闭包函数。装饰器有且仅有一个参数,即函数类型参数。装饰器定义语法如下:
def timer(func):
print("已经执行了")
def inner():
start = time.time()
print("下面执行被装饰函数")
func()
print("被装饰函数执行完毕")
return inner
# 装饰函数,且在装饰是已经运行了timer函数
@timer
def f():
print("hello")
# 调用函数
f()
# 输出函数f的内容
print("输出被装饰后的函数内容:")
print(inspect.getsource(f))
# 运行结果
经执行了
下面执行被装饰函数
hello
被装饰函数执行完毕
输出被装饰后的函数内容:
def inner():
start = time.time()
print("下面执行被装饰函数")
func()
print("被装饰函数执行完毕")
装饰器的能够用于插入日志、性能测试、事务处理、缓存、权限校验等场景。
2、装饰器应用场景
1)带参的被装饰函数
带参数的被装饰函数,装饰函数中的内部函数需要与被装饰函数的参数个数保持一致。
import inspect
# 带参的被装饰函数,inner函数参数个数需要与f函数参数个数一致
def f_func(func):
num3 = 3
def inner(num1, num2):
print("num1:",num1,"num2:",num2)
func(num1,num2)
return inner
@f_func
def f(x, y):
print("x=:",x,"y=:",y)
print(inspect.getsource(f))
f(1,2)
# 运行结果
# def inner(num1, num2):
# print("num1:",num1,"num2:",num2)
# func(num1,num2)
# num1: 1 num2: 2
# x=: 1 y=: 2
2)装饰器升级
装饰函数其目的是需要更好的实现程序扩展,为了能适配更多的被装饰函数,可将装饰函数升级如下:
import inspect
# 装饰函数升级
def f_func(func):
num3 = 3
def inner(*args,**kwargs):
# *args表示任何参数类型和个数,除键值对外,**kwargs表示任何个数的键值对类型参数
print("参数为:",args,kwargs)
func(*args,**kwargs)
return inner
@f_func
def f(x, y, e):
print("x=:",x,"y=:",y)
print(inspect.getsource(f))
f(1,2,e=1)
# 运行结果
# def inner(*args,**kwargs):
# # *args表示任何参数类型和个数,除键值对外,**kwargs表示任何个数的键值对类型参数
# print("参数为:",args,kwargs)
# func(*args,**kwargs)
# 参数为: (1, 2) {'e': 1}
# x=: 1 y=: 2
3)带返回值的被装饰函数
遇到带返回值的被装饰函数,装饰器的内部函数中需要返回函数。具体语法如下:
import inspect
"""被装饰函数带有返回值"""
def f_func(func):
num3 = 3
def inner():
return func()
return inner
@f_func
def f():
return 4
print(inspect.getsource(f))
f1 = f()
print(f1)
# 运行结果
# def inner():
# return func()
# 4
3、使用装饰器实现龟兔赛跑
# 基于装饰器实现龟兔赛跑
import random
import time
track_length = 10
# 定义装饰器
def runtime_log(type):
def runtime(func):
def inner():
print("{}开始奔跑了".format(type))
start_time = time.time()
func()
end_time = time.time()
print("<{}>的运行时间是:{:.2f}".format(type,end_time - start_time))
return inner()
return runtime
@runtime_log("乌龟")
def wugui():
for i in range(1,track_length + 1):
print("乌龟跑了{}米".format(i))
time.sleep(1)
@runtime_log("兔子")
def tuzi():
for i in range(1,track_length + 1):
if i%5 ==0:
time.sleep(random.randint(0,9))
print("兔子跑了{}米".format(i))
wugui()
tuzi()