10分钟挑战 快速了解——闭包和装饰器【Python】

一、闭包

1、概述

        使用了 外部函数变量的 内部函数

2、作用

        保存 函数内的变量,不会随着调用完而被销毁

3、格式
def 外部函数(形参列表):
    a = 10
    def 内部函数(形参列表):
        使用外部函数的变量
    return 内部函数名
4、构成条件
  • 嵌套:函数嵌套是前提
  • 引用:内部函数 使用了 外部函数的变量
  • 返回:外部函数 返回 内部函数名
5、关键字
  • nonlocal:让内部函数 可以修改 外部函数的变量

二、装饰器

1、概述

        本质 就是 闭包函数

2、作用

        不改变 原有函数,给原有函数 增加 额外功能

3、构成条件

        1、有嵌套:函数嵌套是前提
        2、有引用:内部函数 使用了 外部函数的变量
        3、有返回:外部函数 返回 内部函数名
        4、有额外功能:给原有函数 增加 额外功能

4、语法糖

        格式:@装饰器名 

5、重点

        装饰器的 内置函数 格式 = 原函数格式

        即:有参无参,有返回无返回,装饰器的内置函数 和 原函数 要保持一致

三、实操挑战

1、定义一个闭包,用于求解方程的y与x值的变化,例如 y = ax + b。
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 值。

2、创建一个闭包,实现统计函数执行的次数功能。
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,要记得返回内部函数名,最后调用函数即可。

执行结果:

10分钟挑战 快速了解——闭包和装饰器【Python】_第1张图片

3、请使用装饰器方式来统计输出10000句“明天放假咯!”的执行时间。
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包,通过结束时间减去开始时间获得执行时间。需要注意目标函数有形参,所以装饰器的内置函数也需要有形参。

执行结果:

10分钟挑战 快速了解——闭包和装饰器【Python】_第2张图片

4、定义一个函数, 返回字符串, 使用装饰器实现对这个字符串添加后缀.txt。
# 定义一个添加后缀的装饰器
def add(fuc):
    def inner(*args):
        print(fuc(*args) + '.txt')    # 添加后缀并输出
    return inner

@add    # 调用装饰器
def print_info(f_name):    # 定义目标函数接收字符串
    return f_name

print_info('今天星期五')    # 调用函数

解析:在内部函数执行目标函数并添加后缀,通过语法糖调用装饰器。

执行结果:

恭喜你!挑战成功啦~

要多多练习哟

你可能感兴趣的:(Python,python,开发语言)