【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
-
可迭代对象与迭代器的总结
-
一个具备了__iter__方法的对象,就是一个可迭代对象
-
当对一个可迭代对象调用iter()函数时,它会自动调用这个可迭代对象的__iter__方法,这个方法返回的对象当作迭代器
-
当对一个迭代器对象调用next()函数时,他会自动调用这个迭代器对象的__next__方法,这个方法返回想要的数据
-
迭代器一定是可迭代对象,可迭代对象不一定是迭代器
-
数据类型list、dict、str等是Iterable单不是Iterator,不过可以通过iter()函数获得一个Iterator对象
-
迭代器的应用
-
如果每次返回的数据值不是在一个已有的数据集合中,而是通过程序按照一定的规律计算生成的,那就不用再依赖一个已有的数据集合,也就是说不用再将所有要迭代的数据都一次性缓存下来,这样可以节省大量的存储(内存)空间。
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=' ')
生成器
生成器的定义
-
使用了yield关键字的函数不再是函数,而是生成器。
-
yield关键字有两点作用:
-
保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
-
将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return作用
-
可以使用next()函数让生成器从断点处继续执行,唤醒生成器(函数)
-
python3中的生成器可以使用return返回最终运行的返回值
-
生成器是这样一个函数,他记住上一次返回在函数体中的位置。对生成器函数的第二次(或第n次)调用跳转至函数中间,而上次调用的所有的局部变量都保持不变。生成器不仅记住了他的数据状态,生成器还记住了它在流程控制构造(在命令式编程中,这种构造不只是数据值)中的位置。
-
生成器的特点:
-
存储的是生成数据的方式(即算法),而不是存储生成的数据,因此节约内存。
生成器的使用
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修饰的静态变量,也不同于全局变量,它是和闭包函数进行绑定的。
-
闭包函数是函数的嵌套,函数内还有函数,即外层函数嵌套一个内层函数
-
在外层函数定义局部变量,在内层函数通过nonlocal引用,并实现指定功能,比如计数
-
最后外层函数return内层函数
-
主要作用:可以变相实现私有变量的功能,即用内层函数访问外层函数内的变量,并让外层函数内的变量常驻内存
为什么要使用闭包
-
封装变量: 闭包允许你创建一个包含函数和其所在环境中变量的封闭空间。这样,你可以隐藏一些变量,使其不易被外部访问,起到一定的封装作用。
-
保持状态: 闭包函数可以保持其创建时的状态。这意味着你可以在函数外部改变闭包内部的变量,并且在多次调用闭包时保持这些变量的状态。
-
函数工厂: 闭包函数可以用作函数工厂,动态生成函数。这对于根据不同情况生成不同行为的场景很有用。
-
实现装饰器: 闭包函数常用于实现装饰器模式,通过在函数外层包装其他函数来增强其功能,而无需修改原始函数的代码。
-
实现私有变量和方法: 通过闭包,你可以模拟出类似于面向对象编程中的私有变量和方法,限制对内部实现的访问。
闭包的应用场景是什么
创建一个计数器,但又不想让外部直接访问计数变量
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() 时,计数器会递增并返回当前计数值。
这样做的好处是,我们可以创建多个独立的计数器,它们各自维护自己的状态,而不会互相干扰。闭包在这里提供了一种轻量级的状态封装和隔离的机制。
相关文章:
【python高级用法】迭代器、生成器、装饰器、闭包
迭代器 可迭代对象:可以使用for循环来遍历的,可以使用isinstance()来测试。 迭代器:同时实现了__iter__()方法和__next__()方法,可以使用isinstance()方法来测试是否是迭代器对象 from collections.abc import Iterable, Iterat…...
Nx市工业数据洞察:Flask、MySQL、Echarts的可视化之旅
Nx市工业数据洞察:Flask、MySQL、Echarts的可视化之旅 背景数据集来源技术选型功能介绍创新点总结 背景 随着工业化的不断发展,Nx市工业数据的收集和分析变得愈发重要。本博客将介绍如何利用Flask、MySQL和Echarts等技术,从统计局获取的数据…...
关于正态分布
目录 1.正态分布是什么2.正态分布有什么用途3.如何确定数据服从正态分布 本文简单介绍正态分布的基本概念和用途。 1.正态分布是什么 正态分布,也称为高斯分布,是由德国数学家卡尔弗里德里希高斯在研究测量误差时提出的。他发现许多自然现象和统计数据…...
每日一练(编程题-C/C++)
目录 CSDN每日一练1. 2023/2/27- 一维数组的最大子数组和(类型:数组 难度:中等)2. 2023/4/7 - 小艺照镜子(类型:字符串 难度:困难)3. 2023/4/14 - 最近的回文数(难度:中等)4. 2023/2/1-蛇形矩阵(难度:困难)…...
Unity UnityWebRequest 在Mac上使用报CommectionError
今天是想把前两天写的Demo拿到Mac上打个IPA的完事我发现 在运行时释放游戏资源的时候UnityWebRequest返回的结果不是Success 查看Log发现是 req.result 是CommectionError error是 Cannot connect to destination host 代码如下: UnityWebRequest req UnityWebRequ…...
WorkPlus为企业打造私有化部署IM解决方案
在移动数字化时代,企业面临着如何全面掌控业务和生态的挑战。企业微信、钉钉、飞书、Teams等应用虽然提供了部分解决方案,但无法满足企业的私有化部署需求。此时,WorkPlus作为安全专属的移动数字化平台,被誉为移动应用的“航空母舰…...
QT上位机开发(抽奖软件)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 用抽奖软件抽奖,是一种很常见的抽奖方式。特别是写这篇文章的时候,正好处于2023年12月31日,也是一年中最后一天…...
雨课堂作业整理
第一次作业 1.下列序列是图序列的是( ) A.1,2,2,3,4,4,5 B.1,1,2,2,4,6,6 C.0,0,2&am…...
C#/WPF 只允许一个实例程序运行并将已运行程序置顶
使用用互斥量(System.Threading.Mutex): 同步基元,它只向一个线程授予对共享资源的独占访问权。在程序启动时候,请求一个互斥体,如果能获取对指定互斥的访问权,就职运行一个实例。 实例代码: /// <…...
【基础】【Python网络爬虫】【1.认识爬虫】什么是爬虫,爬虫分类,爬虫可以做什么
Python网络爬虫基础 认识爬虫1.什么是爬虫2.爬虫可以做什么3.为什么用 Ptyhon 爬虫4.爬虫的分类通用爬虫聚焦爬虫功能爬虫增量式爬虫分布式爬虫 5.爬虫的矛与盾(重点)6.盗亦有道的君子协议robots7.爬虫合法性探究 认识爬虫 1.什么是爬虫 网络爬虫&…...
【算法与数据结构】860、LeetCode柠檬水找零
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:本题的思路比较简单,首先要保存收到的零钱,其次计算找零,最后分解找…...
「Verilog学习笔记」乘法与位运算
专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 观察乘数的特点: 1111_1011 1_0000_0000 - 1 - 100 timescale 1ns/1nsmodule dajiang13(input [7:0] A,output [15:0] B);//*************code*********…...
CSS与JavaScript的简单认识
CSS:是一门语言,用于控制网页表现,让页面更好看的。 CSS(Cascading Style Sheet):层叠样式表 CSS与html结合的三种方式: 1、内部样式:用style标签,在标签内部定义CSS样式…...
MAC 中多显示器的设置(Parallels Desktop)
目录 一、硬件列表: 二、线路连接: 三、软件设置: 1. 设置显示器排列位置及显示参数 2. 分别设置外接显示器为:扩展显示器,内建显示器为主显示器 3. 设置Parallels Desktop屏幕参数 四、结果 一、硬件列表&a…...
迁移到云原生:如何使用微服务迁移应用程序
企业遇到大规模部署和监督生产中的应用程序的任务。幸运的是,我们可以使用大量技术和工具。然而,从传统的,整体的结构转变为云态一个人提出了自己的障碍。在这里,您会发现将应用程序从整体设置转移到基于微服务的体系结构时要进行…...
kafka 的零拷贝原理
文章目录 kafka 的零拷贝原理 今天来跟大家聊聊kafka的零拷贝原理是什么? kafka 的零拷贝原理 零拷贝是一种减少数据拷贝的机制,能够有效提升数据的效率; 在实际应用中,如果我们需要把磁盘中的某个文件内容发送到远程服务器上…...
华为云Stack 8.X流量模型分析(五)
六、EIP流量模型分析 弹性公网IP(Elastic IP,简称EIP)提供独立的公网IP资源,包括公网IP地址与公网出口带宽服务。如果资源只配置了私网IP,则无法直接访问Internet,为资源配置弹性公网IP后,可…...
学习动态规划解决不同路径、最小路径和、打家劫舍、打家劫舍iii
学习动态规划|不同路径、最小路径和、打家劫舍、打家劫舍iii 62 不同路径 动态规划,dp[i][j]表示从左上角到(i,j)的路径数量dp[i][j] dp[i-1][j] dp[i][j-1] import java.util.Arrays;/*** 路径数量* 动态规划,dp[i][j]表示从左上角到(i,j)的路径数量…...
nodejs微信小程序+python+PHP特困救助供养信息管理系统-计算机毕业设计推荐
目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性:…...
Vue(二):计算属性与 watch 监听器
03. Vue 指令拓展 3.1 指令修饰符 可以通过 . 来指明一些指令的后缀,不同的后缀中封装了不同的操作,可以帮助我们简化代码,比如之前使用过的监听 enter 键的弹起,我们需要操作事件对象,来检测用户使用了哪个键&#…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
