Python闭包函数和计时器

简介: 本文介绍了闭包函数的概念,它允许内部函数引用外部作用域的变量但无法修改它们。示例展示了如何使用闭包来封装函数。接着,文章讨论了如何在函数调用时添加开始和结束的打印语句,通过传递函数作为参数实现。然后,文章引入装饰器,通过闭包定义了一个`timer`装饰器,用于在函数执行前后打印消息。最后,给出了一个练习,实现了一个计算函数执行时间的装饰器,处理了带有参数的被装饰函数。

闭包函数

  • 闭包的内部函数中,对外部作用域的变量进行引用
  • 闭包无法修改外部函数的局部变量
  • 闭包可以保存当前的运行环境
# 普通方法实现
def output_student(name, gender, grade=1):
    print(F"新学期开学啦,学生{name}是{gender},他是{grade}年级学生")


output_student('李白', '男生')
output_student('赵云', '男生')
output_student('孙尚香', '女生')
# 闭包函数
def student_grade(grade):
    def output_student(name, gender):
        print(F"新学期开学啦,学生{name}是{gender},他是{grade}年级学生")
    return output_student


student_info = student_grade(3)
student_info('李白', '男生')
student_info('赵云', '男生')
student_info('孙尚香', '女生')

需求:在函数调用的时候打印函数开始和函数结束

def aaa():
    print('good good study, happy happy everyday')


def bbb():
    print('everything is ok')


# 把中间的执行函数使用参数替代
def function_tips(func):
    print("函数开始执行")
    # 不写死函数,使用外部调用的方式
    func()
    print("函数结束执行")


# 传入一个函数对象
function_tips(bbb)

代码运行步骤:
image.png

func参数等于上方的bbb函数,下方调用func就等于调用bbb函数,然后把bbb的内容带入func
image.png

最后执行代码实现

image.png

使用装饰器实现

# 使用装饰器实现
# 闭包定义,1、定义两个函数,一个内函数,一个外函数,timer是外函数
# 5、在装饰器执行的过程中传入一个参数,这个参数就是被装饰函数的对象
def timer(func):
    # inner作用:执行装饰器的逻辑;inner是内函数
    def inner():
        # 2、在内函数里面添加装饰器的逻辑
        print("代码开始运行")
        func()  # 6、添加被装饰函数的执行步骤
        print("代码结束运行")
    # 3、把内函数返回出去,之后可以被调用
    return inner


# 4、装饰器的使用:@+装饰器名称
@timer
def aaa():
    print('ccccc')


aaa()

---------->
代码开始运行
ccccc
代码结束运行

装饰器的练习

题目:实现一个计时器的装饰器,计算函数的执行时间

import datetime


def timer(func):
    def inner():
        # 获取当前时间
        start_time = datetime.datetime.now()
        func()
        # 获取结束时间
        end_time = datetime.datetime.now()
        print(f"函数执行时间{end_time - start_time}")

    return inner


@timer
def calc():
    print("aaaaaaa")


calc()

------------------------------->
aaaaaaa
函数执行时间0:00:00

被装饰函数存在参数怎么解决

# 装饰器的练习
# 题目:实现一个计时器的装饰器,计算函数的执行时间
import datetime


def timer(func):
    """
    1、如果装饰器内有参数,需要写在内置函数内,在调用的时候也要带上
    2、如果写死一个参数,但无法确定被装饰器的参数数量,这种写法会报错
    3、解决方法:把两个地方的参数全部换成不定长参数*args, **kwargs
    :param func:
    :return:
    """
    def inner(*args, **kwargs):
        # 获取当前时间
        start_time = datetime.datetime.now()
        func(*args, **kwargs)
        # 获取结束时间
        end_time = datetime.datetime.now()
        print(f"函数执行时间{end_time - start_time}")

    return inner


@timer
def calc(name, age, gender):
    print("aaaaaaa")
    print(name)
    print(age)
    print(gender)


calc('lili', 3, "女")

-------------------------------->
aaaaaaa
lili
3
女
函数执行时间0:00:00
相关文章
|
11月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
564 2
|
11月前
|
算法 Java Docker
(Python基础)新时代语言!一起学习Python吧!(三):IF条件判断和match匹配;Python中的循环:for...in、while循环;循环操作关键字;Python函数使用方法
IF 条件判断 使用if语句,对条件进行判断 true则执行代码块缩进语句 false则不执行代码块缩进语句,如果有else 或 elif 则进入相应的规则中执行
1726 1
|
11月前
|
Java 数据处理 索引
(numpy)Python做数据处理必备框架!(二):ndarray切片的使用与运算;常见的ndarray函数:平方根、正余弦、自然对数、指数、幂等运算;统计函数:方差、均值、极差;比较函数...
ndarray切片 索引从0开始 索引/切片类型 描述/用法 基本索引 通过整数索引直接访问元素。 行/列切片 使用冒号:切片语法选择行或列的子集 连续切片 从起始索引到结束索引按步长切片 使用slice函数 通过slice(start,stop,strp)定义切片规则 布尔索引 通过布尔条件筛选满足条件的元素。支持逻辑运算符 &、|。
484 0
|
12月前
|
设计模式 缓存 监控
Python装饰器:优雅增强函数功能
Python装饰器:优雅增强函数功能
427 101
|
12月前
|
缓存 测试技术 Python
Python装饰器:优雅地增强函数功能
Python装饰器:优雅地增强函数功能
348 99
|
12月前
|
存储 缓存 测试技术
Python装饰器:优雅地增强函数功能
Python装饰器:优雅地增强函数功能
594 98
|
12月前
|
缓存 Python
Python中的装饰器:优雅地增强函数功能
Python中的装饰器:优雅地增强函数功能
|
Python
Python 函数定义
Python 函数定义
1017 155
|
PHP Python
Python format()函数高级字符串格式化详解
在 Python 中,字符串格式化是一个重要的主题,format() 函数作为一种灵活且强大的字符串格式化方法,被广泛应用。format() 函数不仅能实现基本的插入变量,还支持更多高级的格式化功能,包括数字格式、对齐、填充、日期时间格式、嵌套字段等。 今天我们将深入解析 format() 函数的高级用法,帮助你在实际编程中更高效地处理字符串格式化。
822 0
|
索引 Python 容器
[oeasy]python096_列表_计数函数_count
本教程详细介绍了Python中列表的计数方法`count`,包括其基本用法、与`len`函数的区别,以及如何结合索引操作查找和删除特定元素。同时探讨了字符串对象的`count`方法,并通过实例演示了如何统计字符出现次数。
331 7

推荐镜像

更多