当前位置:
首页 > temp > 简明python教程 >
-
python基础-闭包函数和装饰器
闭包函数和装饰器
闭包函数
- 概念:在函数中(嵌套)定义另一个函数时,内部函数引用了外层函数的名字。
-
特性
- 闭包函数必须在函数内部定义
- 闭包函数可引用外层函数的名字
闭包函数是函数嵌套、函数对象、名称空间与作用域结合体
闭包中被内部函数引用的变量,不会因为外部函数结束而被释放掉,而是一直存在内存中,直到内部函数被调用结束
# 闭包函数的定义
def func(y):
x = 100
def inner(): # 此处的inner 就是闭包函数
print(x)
print(y)
return inner
# 闭包函数的调用
inner = func(1000)
inner()
- 应用:为了给装饰器的使用做准备
装饰器
-
概念:在不修改被装饰对象源代码与调用方式的前提下,添加新的功能。简单来说,就是给其他函数增加额外功能的函数
-
装饰器必须遵循“开放封闭”原则
- 开放:对函数功能的添加是开放的
- 封闭:对函数功能的修改是封闭的
-
必备条件:
- 不能改变被装饰对象源代码
- 为被装饰对象添加新的功能
- 不能改变被装饰对象调用方式
-
使用装饰器,可以解决代码冗余问题,提高代码的可扩展性
-
应用:统计时间、登录认证
说了这多理论,上代码。
需求:统计下载媒体文件的时间(简易版)
# 需求: 统计下载电影的时间。
# 一般我们实现这个功能的方式如下
import time
def download_movie():
"""
下载电影功能
:return: None
"""
print("电影下载开始了……")
time.sleep(2) # 模拟电影下载2 秒
print("下载完成")
start_time = time.time() # 获取当前时间戳
download_movie() # 下载电影
end_time = time.time() # 获取当前时间戳
print(f"下载时间:{end_time-start_time}")
以上代码确实实现了统计下载时间的功能,问题来了,如果我有多个类型文件下载函数,都需要统计时间呢?难道展现我们的“CV大法”?估计隔天就要被扫地出门了……
就没有什么办法可以解决了吗?当然有啦!先看代码
# 定义一个装饰器
def time_record(func):
"""
新增统计时间功能
:param func: 使用该功能的函数对象
:return: inner 函数对象
"""
def inner():
# 统计开始
start_time = time.time()
func() # func() ----→ download_movie() or download_music()
end_time = time.time()
# 统计结束,打印统计时间
print(f"下载时间:{end_time-start_time}")
return inner
def download_movie():
"""
模拟下载电影
:return: None
"""
print("电影下载开始了……")
time.sleep(2)
print("下载完成!")
def download_music():
"""
模拟下载音乐
:return: None
"""
print("歌曲下载开始了……")
time.sleep(2)
print("下载完成!")
# time_record(download_movie) 返回一个inner,将其赋值给download_movie
inner = time_record(download_movie)
inner() # inner() ----→ download_movie()
# time_record(download_music) 返回一个inner,将其赋值给download_music
inner1 = time_record2(download_music)
inner1()
以上代码就是对装饰器的引入,其中 time_record
就是装饰器,download_movie
和 download_music
就是被装饰的函数对象。
通过观察
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数