【python高级用法】迭代器、生成器、装饰器、闭包

迭代器

  • 可迭代对象:可以使用for循环来遍历的,可以使用isinstance()来测试。

  • 迭代器:同时实现了__iter__()方法和__next__()方法,可以使用isinstance()方法来测试是否是迭代器对象


from collections.abc import Iterable, Iterator
li = [11, 22, 33, 44, 55]print(isinstance(li, Iterable)
iterator_li = iter(li)
print(isinstance(iterator_li, Iterator)

使用类实现迭代器

两个类实现一个迭代器


class MyList(object):"""自定义的一个可迭代对象"""def __init__(self):self.items = []def add(self, val):self.items.append(val)def __iter__(self):#python中万物皆对象,将该类对象的引用self作为实参传入到MyIterator类中myiterator = MyIterator(self)return myiteratorclass MyIterator(object):"""自定义的供上面可迭代对象使用的一个迭代器"""#这里的mylist就MyList对象def __init__(self, mylist):self.mylist = mylist# current用来记录当前访问到的位置#每一次调用for循环时,索引位置都从零开始self.current = 0def __next__(self):if self.current < len(self.mylist.items):item = self.mylist.items[self.current]self.current += 1return itemelse:raise StopIterationdef __iter__(self):return self

一个类实现迭代器


class MyList(object):"""自定义的一个可迭代对象"""def __init__(self):self.items = []self.current = 0def add(self, val):self.items.append(val)def __iter__(self):#返回自身引用,自己本身就是一个迭代器对象return selfdef __next__(self):if self.current < len(self.items):item = self.items[self.current]self.current += 1return itemelse:#使用for循环第二次遍历时,self.current可以从0开始self.current = 0raise StopIteration
  • 可迭代对象与迭代器的总结

  1. 一个具备了__iter__方法的对象,就是一个可迭代对象

  1. 当对一个可迭代对象调用iter()函数时,它会自动调用这个可迭代对象的__iter__方法,这个方法返回的对象当作迭代器

  1. 当对一个迭代器对象调用next()函数时,他会自动调用这个迭代器对象的__next__方法,这个方法返回想要的数据

  1. 迭代器一定是可迭代对象,可迭代对象不一定是迭代器

  1. 数据类型list、dict、str等是Iterable单不是Iterator,不过可以通过iter()函数获得一个Iterator对象

  • 迭代器的应用

  1. 如果每次返回的数据值不是在一个已有的数据集合中,而是通过程序按照一定的规律计算生成的,那就不用再依赖一个已有的数据集合,也就是说不用再将所有要迭代的数据都一次性缓存下来,这样可以节省大量的存储(内存)空间。


class FeiboIterator(object):"""斐波那契数列迭代器"""def __init__(self, n):# 斐波那数列值的个数self.n = n# 记录当前遍历的下标self.index = 0# 斐波那数列前面的两个值self.num1 = 0self.num2 = 1def __next__(self):"""被next()函数调用来获取下一个数"""if self.index < self.n:num = self.num1self.num1, self.num2 = self.num2, self.num1 + self.num2self.index += 1return numelse:raise StopIterationdef __iter__(self):"""迭代器的__iter__返回自身即可"""return selfif __name__ == '__main__':fb = FeiboIterator(20)for num in fb:print(num, end=' ')

生成器

生成器的定义

  1. 使用了yield关键字的函数不再是函数,而是生成器。

  1. yield关键字有两点作用:

  • 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起

  • 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return作用

  1. 可以使用next()函数让生成器从断点处继续执行,唤醒生成器(函数)

  1. python3中的生成器可以使用return返回最终运行的返回值

  1. 生成器是这样一个函数,他记住上一次返回在函数体中的位置。对生成器函数的第二次(或第n次)调用跳转至函数中间,而上次调用的所有的局部变量都保持不变。生成器不仅记住了他的数据状态,生成器还记住了它在流程控制构造(在命令式编程中,这种构造不只是数据值)中的位置。

  1. 生成器的特点:

  • 存储的是生成数据的方式(即算法),而不是存储生成的数据,因此节约内存。

生成器的使用


def create_points():k = 2b = 1x = 0while True:y = k * x + b#当使用send方法时,会将send方法中的参数赋给temp,send()方法与next()方法类似,都可以取生成器中的下一个元素。temp = yield (x,y)if temp:k, b = tempx = yif __name__ == '__main__':#不再是一个普通函数的调用,因为函数体内包含yield关键字,此时是生成一个生成器对象g = create_points()# print(next(g))# print(next(g))# print(g.send((3, 4)))# print(next(g))# print(next(g))count = 0for i in g:if count > 3:breakprint(i)count += 1

参考链接:

python生成器的原理和业务场景下的使用_for line in tqdm(f, desc='read sentence_cuts'):如果不-CSDN博客

装饰器

装饰器的定义

装饰器可以在不改变某函数结构和调用方式基础之上,为其增加新的功能,并且最大化复用新的功能。

装饰器的应用场景

为函数增加日志记录、登录校验、权限校验等,我们可以将这些功能写成一个装饰器,然后直接应用到相应需要改功能的函数中即可,可以保证对原代码和函数零侵入。

装饰器的本质是一个闭包函数

  • 装饰器函数
def timing_decorator(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)end_time = time.time()execution_time = end_time - start_timeprint(f"{func.__name__} cost time: {execution_time:.4f} s")return resultreturn wrapper
  • 构造执行函数
@timing_decorator
def demo():time.sleep(5)

执行demo函数时,会打印该函数执行时间为5s

参考文献:

python装饰器全解--包含实现原理及应用场景_装饰器实现原理-CSDN博客

闭包

什么是闭包

概念:一个函数可以引用作用域外的变量,同时也可以在函数内部进行使用的函数,称之为闭包函数。而这个作用域外的变量,称之为自由变量。这个自由变量不同于C++的static修饰的静态变量,也不同于全局变量,它是和闭包函数进行绑定的。

  1. 闭包函数是函数的嵌套,函数内还有函数,即外层函数嵌套一个内层函数

  1. 在外层函数定义局部变量,在内层函数通过nonlocal引用,并实现指定功能,比如计数

  1. 最后外层函数return内层函数

  1. 主要作用:可以变相实现私有变量的功能,即用内层函数访问外层函数内的变量,并让外层函数内的变量常驻内存

为什么要使用闭包

  1. 封装变量: 闭包允许你创建一个包含函数和其所在环境中变量的封闭空间。这样,你可以隐藏一些变量,使其不易被外部访问,起到一定的封装作用。

  2. 保持状态: 闭包函数可以保持其创建时的状态。这意味着你可以在函数外部改变闭包内部的变量,并且在多次调用闭包时保持这些变量的状态。

  3. 函数工厂: 闭包函数可以用作函数工厂,动态生成函数。这对于根据不同情况生成不同行为的场景很有用。

  4. 实现装饰器: 闭包函数常用于实现装饰器模式,通过在函数外层包装其他函数来增强其功能,而无需修改原始函数的代码。

  5. 实现私有变量和方法: 通过闭包,你可以模拟出类似于面向对象编程中的私有变量和方法,限制对内部实现的访问。

闭包的应用场景是什么

创建一个计数器,但又不想让外部直接访问计数变量

def create_counter():count = 0  # 这个变量在闭包内def counter():nonlocal count  # 使用 nonlocal 关键字声明 count 不是局部变量count += 1return countreturn counter# 创建一个计数器
my_counter = create_counter()# 使用计数器
print(my_counter())  # 输出 1
print(my_counter())  # 输出 2
print(my_counter())  # 输出 3

在这个例子中,create_counter 函数返回了一个内部定义的 counter 函数count 变量被封装在 counter 函数的闭包中,因此外部无法直接访问。每次调用 my_counter() 时,计数器会递增并返回当前计数值。

这样做的好处是,我们可以创建多个独立的计数器,它们各自维护自己的状态,而不会互相干扰。闭包在这里提供了一种轻量级的状态封装和隔离的机制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/587924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

驾驶人类未来:Apollo自动驾驶系统的影响力

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 ChatGPT体验地址 文章目录 前言1. 什么是自定义指令&#xff1f;2. Apollo中的自定义指令2.1 查询中的自定义指令2.2 变更操作中的自定义指令 3. 自定义指令的实现结论 文章目录 前言1. 什…

中职网络安全Server2002——Web隐藏信息获取

B-2&#xff1a;Web隐藏信息获取 任务环境说明&#xff1a; 服务器场景名&#xff1a;Server2002&#xff08;关闭链接&#xff09;服务器场景用户名&#xff1a;未知 有问题需要环境加q 通过本地PC中渗透测试平台Kali使用Nmap扫描目标靶机HTTP服务子目录&#xff0c;将扫描子…

蓝桥杯python比赛历届真题99道经典练习题 (61-70)

【程序61】 题目:打印出杨辉三角形(要求打印出10行如下图)    1.程序分析: if __name__ == __main__:a = []for i in range(10):a.append([])for j in range(10):a[i].append(0)for i in range(10):a[i][0] = 1a[i][i] = 1for i in range(2,10):for j in range(1,i):…

如何理解鼠标点击事件在程序中的处理

在计算机用户界面中&#xff0c;鼠标点击是一个常见的交互动作。那么&#xff0c;当你按下鼠标时&#xff0c;程序是如何知道这个点击是否针对它自己的按钮的呢&#xff1f;本文将探讨鼠标点击事件在操作系统和应用程序之间的传递过程。 鼠标点击事件的捕获 当你按下鼠标按钮…

2023-12-19 LeetCode每日一题(寻找峰值 II)

2023-12-19每日一题 一、题目编号 1901. 寻找峰值 II二、题目链接 点击跳转到题目位置 三、题目描述 一个 2D 网格中的 峰值 是指那些 严格大于 其相邻格子(上、下、左、右)的元素。 给你一个 从 0 开始编号 的 m x n 矩阵 mat &#xff0c;其中任意两个相邻格子的值都 不…

P5729 【深基5.例7】工艺品制作题解

题目 现有一个长宽高分别为w,x,h组成的实心玻璃立方体&#xff0c;可以认为是由111的数个小方块组成的&#xff0c;每个小方块都有一个坐标(i,j,k)。现在需要进行q次切割。每次切割给出(x1​,y1​,z1​),(x2​,y2​,z2​)这 6 个参数&#xff0c;保证x1​≤x2​&#xff0c;y1​…

详解数组的轮转

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

2023.12.31 python总结

目录 1.python语法 2.基础语句 3.容器 4.函数 5.语法进阶 6.文件操作 7.异常处理 8.模块 9.正则表达式 10.pymysql,pandas 11.闭包装饰器 12. 多进程多线程 13.网络编程 14.面向对象 1.python语法 注释 命名规则:大小驼峰,蛇形 数据类型: int,float,bool,strin…

自动驾驶代客泊车AVP巡航规划详细设计

目 录 巡航规划详细设计... 1 修改记录... 2 目 录... 3 1 背景... 5 2 系统环境... 6 2.1 巡航规划与其它模块联系... 6 2.2 巡航规划接口说明... 6 3 规划模块设计... 9 3.1 巡航规划架构图... 9 3.2 预处理... 10 3.3 Planner. 10 3.3.1 Geometry planner. 10 …

C语言——扫雷

扫雷是一款经典的小游戏&#xff0c;那如何使用C语言实现一个扫雷游戏呢&#xff1f; 一、全部源码 直接把全部源码放在开头&#xff0c;如有需要&#xff0c;直接拿走。 源码分为三个文件&#xff1a; test.cpp/c 主函数的位置 #include "game.h"int main() {…

[设计模式 Go实现] 创建型~抽象工厂模式

抽象工厂模式用于生成产品族的工厂&#xff0c;所生成的对象是有关联的。 如果抽象工厂退化成生成的对象无关联则成为工厂函数模式。 比如本例子中使用RDB和XML存储订单信息&#xff0c;抽象工厂分别能生成相关的主订单信息和订单详情信息。 如果业务逻辑中需要替换使用的时候…

Python开源项目月排行 2023年12月

Python 趋势月报&#xff0c;按月浏览往期 GitHub,Gitee 等最热门的Python开源项目&#xff0c;入选的项目主要参考GitHub Trending,部分参考了Gitee和其他。排名不分先后&#xff0c;都是当前月份内相对热门的项目。 入选公式&#xff1d;70%GitHub Trending20%Gitee10%其他 …

LFW人脸数据库的简介

LFW人脸数据库的简介 ​ LFW (Labled Faces in the Wild)人脸数据集&#xff1a;是目前人脸识别的常用测试集&#xff0c;其中提供的人脸图片均来源于生活中的自然场景&#xff0c;因此识别难度会增大&#xff0c;尤其由于多姿态、光照、表情、年龄、遮挡等因素影响导致即使同…

每日一练(编程题-C/C++)

目录 CSDN每日一练1. 2023/2/27- 一维数组的最大子数组和(类型&#xff1a;数组 难度&#xff1a;中等)2. 2023/4/7 - 小艺照镜子(类型&#xff1a;字符串 难度&#xff1a;困难)3. 2023/4/14 - 最近的回文数(难度&#xff1a;中等)4. 2023/2/1-蛇形矩阵(难度&#xff1a;困难)…

【Spring Security】AuthenticationFailureHandler 用户认证失败后处理

文章目录 前言简单介绍官方默认用户认证失败后处理器SimpleUrlAuthenticationFailureHandlerForwardAuthenticationFailureHandlerExceptionMappingAuthenticationFailureHandlerDelegatingAuthenticationFailureHandler 自定义使用SecurityConfiguration 配置 前言 Authentic…

Hive自定义函数详解

1.hive函数各种命令 查看系统自带的函数 hive> show functions; -- 显示自带的函数的用法 hive> desc function upper; -- 详细显示自带的函数的用法 hive> desc function extended upper; -- 添加jar包到hive中 add jar /data/xx.jar; -- 创建自定义函数 create fu…

算法基础之整数划分

整数划分 核心思想&#xff1a; 计数类dp 背包做法 f[i][j] 表示 取 1 – i 的物品 总容量为j的选法数量 f[i][j] f[i-1][j] f[i-1][j-v[i]] f[i-1][j-2v[i]] f[i-1][j-3v[i]] ……f[i-1][j-kv[i]] f[i][j-v[i]] f[i-1][j-v[i]] f[i-1][j-2v[i]] f[i-1][j-3v[i]] ……f[i…

万字长文谈自动驾驶occupancy感知

文章目录 prologuepaper listVision-based occupancy :1. [MonoScene: Monocular 3D Semantic Scene Completion [CVPR 2022]](https://arxiv.org/pdf/2112.00726.pdf)2. [Tri-Perspective View for Vision-Based 3D Semantic Occupancy Prediction [CVPR 2023]](https://arxiv…

Docker Harbor私有镜像image仓库安装

Docker Harbor私有镜像image仓库安装 goharbor/harbor 参考&#xff1a;https://www.cnblogs.com/wuvikr/p/14688079.html #停止harbor systemctl stop harbor.service 使用prepare脚本重新加载harbor.yml中的配置 [rootharbor harbor]#./prepare 稍等一会harbor会自动启动起来…

QString设置小数点精度位数

QString设置小数点精度位数 Chapter1 QString设置小数点精度位数Chapter2 Qt中QString.toDouble有效位数6位问题以及数据小数点有效位数的处理问题一&#xff1a;QString.toDouble有效位只有6位问题二:小数点有效位数的问题 Chapter3 qt QString转Double只显示6位数字的问题(精…