使用了 外部函数变量的 内部函数
保存 函数内的变量,不会随着调用完而被销毁
def 外部函数(形参列表):
a = 10
def 内部函数(形参列表):
使用外部函数的变量
return 内部函数名
本质 就是 闭包函数
不改变 原有函数,给原有函数 增加 额外功能
1、有嵌套:函数嵌套是前提
2、有引用:内部函数 使用了 外部函数的变量
3、有返回:外部函数 返回 内部函数名
4、有额外功能:给原有函数 增加 额外功能
格式:@装饰器名
装饰器的 内置函数 格式 = 原函数格式
即:有参无参,有返回无返回,装饰器的内置函数 和 原函数 要保持一致
def equation(a, b): # 定义外部函数,接收 a, b
def inner(x): # 定义内部函数,接收 x
return a * x + b # 内部函数返回方程式
return inner # 返回内部函数名
equ = equation(2, 1) # 创建一个对应 y = 2x + 1的函数
print(equ(3)) # 输出7,因为 3对应 x的值,2*3 + 1 = 7
解析:在这个例子中,equation 函数接受两个参数 a 和 b,并返回一个新的函数 inner。这个新函数接受一个参数 x,并返回对应的 y 值。这就是一个闭包,因为它可以记住 a 和 b 的值,即使在equation 函数已经返回后,我们仍然可以使用这个闭包来求解新的 y 值。
def func_count(): # 定义外部函数 用于计数
count = 0 # 计数初始化
def inner():
print('hello!小林') # 打印内容
nonlocal count # 使用nonlocal关键字,允许内部函数调用外部函数的变量
count += 1 # 计数加1
print(f'执行了{count}次') # 打印执行次数
return inner # 有返回
my_fuc = func_count() # 调用函数
my_fuc()
my_fuc()
my_fuc()
解析:在这个例子中,我们首先定义了一个外部函数 func_count,并在其中初始化计数值,在内部函数中打印内容,使用 nonlocal 关键字,允许内部函数 inner 调用外部函数 func_count 的变量 count,并在执行一次后计数加1,要记得返回内部函数名,最后调用函数即可。
执行结果:
import time # 导入time包
# 定义一个装饰器来统计执行时间
def print_time(fuc): # 外部函数接收目标函数
def inner(*args):
start = time.time() # 获取开始时间
result = fuc(*args) # 执行目标函数
end = time.time() # 获取结束时间
print(f'执行时间为{end - start:.5f}') # 打印执行时间,保留小数点后5位
return result # 返回函数结果
return inner # 返回内部函数名
# 使用装饰器来装饰目标函数
@print_time
def print_info(num): # 接收打印次数
for i in range(num - 1):
print("明天放假咯!")
# 调用装饰后的函数
print_info(10000)
解析:本例需要导入time包,通过结束时间减去开始时间获得执行时间。需要注意目标函数有形参,所以装饰器的内置函数也需要有形参。
执行结果:
# 定义一个添加后缀的装饰器
def add(fuc):
def inner(*args):
print(fuc(*args) + '.txt') # 添加后缀并输出
return inner
@add # 调用装饰器
def print_info(f_name): # 定义目标函数接收字符串
return f_name
print_info('今天星期五') # 调用函数
解析:在内部函数执行目标函数并添加后缀,通过语法糖调用装饰器。
执行结果:
恭喜你!挑战成功啦~
要多多练习哟