Python中的三器一闭(详细版)

news2025/7/20 13:05:45

python中的三器一闭

  • 迭代器
    • 什么是迭代
    • 什么是可迭代对象
    • 判断数据是否可迭代
    • 什么是迭代器
    • 迭代器的本质
    • 使用迭代器取数据
    • 自定义迭代器
  • 生成器
    • 创建生产器的方法
    • 关键字yield
    • next和send
  • 装饰器
    • 装饰器的功能
    • 定义装饰器
  • 闭包
    • 什么是闭包
    • 函数、匿名函数、闭包、对象 当做实参时的区别

迭代器

什么是迭代

迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。

在python中,迭代是访问集合元素的一种方式。对list、tuple、str等类型的数据使用for…in…的循环语法从其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代。

什么是可迭代对象

一个对象如果实现了__iter__方法(魔法方法),那么我们称这个对象是可迭代对象。

或者可以这样理解,只要是可以通过for…in…的形式进行遍历的,那么这个数据类型就是可以迭代的。

判断数据是否可迭代

python中要判断一个对象是否是可迭代的,可以用collections模块中的Iterable来进行判断。isinstance函数会返回True或False来表明对象是(True)或者不是(False)可迭代对象。

from collections.abc import Iterable

print(isinstance(["abc"], Iterable))
print(isinstance([100], Iterable))


在这里插入图片描述

什么是迭代器

迭代器的作用是用来访问容器(用来保存元素的数据结构)中的元素,所以使用迭代器,我们就可以访问容器中里面的元素。

迭代器是一个可以记住遍历的位置的对象。迭代器对象从第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器的本质

我们可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。

使用迭代器取数据

from collections.abc import Iterator

nums = [3, 6, 8]  # 可迭代对象
nums = iter(nums)  # 创建了迭代器
print("nums", isinstance(nums, Iterator))  # 判断是否是迭代器
# 取出迭代器的数据
num1 = next(nums)
print(num1)
num1 = next(nums)
print(num1)
num1 = next(nums)
print(num1)

在这里插入图片描述

若迭代的次数超过了可迭代对象的长度, 就会报StopIteration异常。

自定义迭代器

使用__iter__和__next__方法自定义迭代器

只要在类中,定义__iter__方法,那么这个类创建出来的对象一定是可迭代对象

如果类中实现了__iter__方法和__next__方法的对象,就是迭代器。

当我们调用iter()函数提取一个可迭代对象的 迭代器时,实际上会自动调用这个对象的__iter__方法,并且这个方法返回迭代器。

# 使用迭代器完成学生管理系统
class StuSystem(object):
    """
    学生管理系统
    """
    def __init__(self):
        self.stus = []
        self.current_num = 0

    def add(self):
        """
        添加一个新的学生
        :return:
        """
        name = input("请输入新学生的姓名:")
        tel = input("请输入新学生的手机号:")
        address = input("请输入新学生的住址:")
        new_stu = dict()
        new_stu["name"] = name
        new_stu["tel"] = tel
        new_stu["address"] = address
        self.stus.append(new_stu)

    def __iter__(self):
        return self

    def __next__(self):
        if self.current_num < len(self.stus):
            ret = self.stus[self.current_num]
            self.current_num += 1
            return ret
        else:
            self.current_num = 0
            raise StopIteration

# 创建对象
stu = StuSystem()

# 添加信息
stu.add()
stu.add()
stu.add()

stus = [x for x in stu]

print(stus)

在这里插入图片描述

凡是可作用于for循环的对象都是Iterable 类型;
凡是可作用于 next() 函数的对象都是Iterator 类型;
集合数据类型如list 、dict、str等是 Iterable但不是Iterator,不过可以通过 iter()函数获得一个Iterator对象。

生成器

一边循环一边计算的机制,称为生成器(generator)

在Python中,使用了yield的函数被称为生成器。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作。生成器函数一般是通过for循环调用,for循环自带next方法。

创建生产器的方法

1.将列表推导式的[]改为()
2.在函数中使用yield关键字,函数就变成了一个generator

使用生成器完成斐波那契数列

def fib_generator():
    num1 = 1
    num2 = 1
    while True:
        temp_num = num1
        num1, num2 = num2, num1+num2
        # return temp_num  # 方式1代码
        yield temp_num

# 方式1代码(方式1不能够生成1,1,2,3,5...斐波那契数列)
# print(fib_generator())
# print(fib_generator())
# print(fib_generator())
# print(fib_generator())

# 方式2代码(可以生成斐波那契数列)
fib = fib_generator()
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))

在这里插入图片描述

关键字yield

yield是一个类似return的关键字。当我们调用这个函数的时候并不是返回计算的结果。而是返回一个生成器。只有迭代这个生成器的时候才会计算结果。

next和send

next()方法:
在调用生成器运行的过程中,每次遇到 yield ,函数返回当前的值,并且会暂停并保存当前所有的运行信息, 并在下一次执行 next() 方法时从当前位置继续运行。

send()方法:
先理解个概念【休眠】:意思就是暂时保留先不进行,等待需要时再进行。作用与next()作用相似
区别:
1.send(value)可以传递value给yield,即:我们可以指定yield返回啥就返回啥,
2.next()不能传递特定的值,只能传递None进去。

def genterator_test():
    while True:
        print("--1-")
        num = yield 100
        print("--2--", "num=", num)


g = genterator_test()
print(g.send(None))
print(g.send(11))
print(g.send(22))

在这里插入图片描述

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

装饰器

装饰器是给现有的模块增添新的小功能,可以对原函数进行功能扩展,而且还不需要修改原函数的内容,也不需要修改原函数的调用。

装饰器的功能

装饰器的实现是由闭包支撑的;
装饰器本质上是⼀个python函数,它可以在让其他函数在不需要做任何代码的变动的前提下增加额外的功能;
装饰器的返回值也是⼀个函数的对象,它经常用于有切面需求的场景,实现路由传参,flask的路由传参依赖于装饰器,浏览器通过url访问到装饰器的路由,从而访问视图函数获得返回的HTML页面;

定义装饰器

def check_login(func):
    def inner():
        # 验证1
        # 验证2
        # 验证3
        func()

    return inner


@check_login
def f1():
    print('f1')

def check_login(func):
    def inner():
        # 验证1
        if "admin" != input("请输入用户名:"):
            return "用户名不正确"
        # 验证2
        if "123456" != input("请输入密码:"):
            return "密码不正确"
        # 验证3
        if "7788" != input("请输入手机短信验证码:"):
            return "验证码不正确"

        func()

    return inner


@check_login
def f1():
    print('f1')


f1()  # 调用f1函数

闭包

什么是闭包

如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).

# 定义函数可以理解为:
# 定义了一个全局变量,其变量名字是函数的名字,即test
# 这个test变量指向了一个代码块,这个代码块是函数
# 其实就是说test保存了一个代码块的地址,即引用
def test():
    print("--- in test func----")

test()  # 这是调用函数

ret = test # 用另外一个变量 复制了 test这个引用,导致ret变量也指向那个 函数代码块

# 下面输出的2个地址信息是相同的
print(id(ret))
print(id(test))

# 通过引用调用函数
ret()

函数、匿名函数、闭包、对象 当做实参时的区别

匿名函数能够完成基本的简单功能,,,传递是这个函数的引用 只有功能
普通函数能够完成较为复杂的功能,,,传递是这个函数的引用 只有功能
闭包能够将较为复杂的功能,,,传递是这个闭包中的函数以及数据,因此传递是功能+数据
对象能够完成最为复杂的功能,,,传递是很多数据+很多功能,因此传递是功能+数据

悲索之人烈焰加身,堕落者不可饶恕。永恒燃烧的羽翼,带我脱离凡间的沉沦。

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

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

相关文章

Blazor_WASM之3:项目结构

Blazor_WASM之3&#xff1a;项目结构 Blazor WebAssembly项目模板可选两种&#xff0c;Blazor WebAssemblyAPP及Blazor WebAssemblyAPP-Empty 如果使用Blazor WebAssemblyAPP模板&#xff0c;则应用将填充以下内容&#xff1a; 一个 FetchData 组件的演示代码&#xff0c;该…

蓝桥杯-最优清零方案(2022省赛)

蓝桥杯-最优清零方案1、问题描述2、解题思路3、代码实现1、问题描述 给定一个长度为 N 的数列 1,2,⋯,A1,A2,...,ANA_1,A_2,...,A_NA1​,A2​,...,AN​ 。现在小蓝想通过若干次操作将 这个数列中每个数字清零。 每次操作小蓝可以选择以下两种之一: 1. 选择一个大于 0 的整数, 将…

杂记——18.VSCode的下载及使用

这篇文章&#xff0c;我们来讲一下VSCode&#xff0c;讲一下如何下载及使用VSCode 目录 1.VSCode的下载 1.1VSCode的简介 1.2VSCode的下载与安装 1.2.1下载 1.2.2安装 2.VSCode的使用 2.1界面 2.2基础设置 2.3禁用自动更新 2.3自动保存设置 2.4Vscode更换主题 2.5…

Hive面试题-HQL转换MapReduce底层核心逻辑剖析

视频可查看&#xff1a;https://www.bilibili.com/video/BV1RV41147Tb/?spm_id_from333.999.0.0&vd_source3ba3c3ba31427f60d734ede7a948de4a 原文地址&#xff1a;Hive学习之路 &#xff08;二十&#xff09;Hive 执行过程实例分析 - 扎心了&#xff0c;老铁 - 博客园 (c…

K_A14_012基于STM32等单片机驱动GY-25倾斜度角度模块 串口与OLED0.96双显示

K_A14_012基于STM32等单片机驱动GY-25倾斜度角度模块 串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCGY-25倾斜度角度模块1.2、STM32F103C8T6GY-25倾斜度角度模块五、基础知识学习与相关资料下…

测试按方向的分类

按方向分(都是在系统测试阶段测试的) 功能测试&#xff1a;举例说明什么是功能 性能测试 ①压力测试&#xff1a;不断地增加压力&#xff0c;从而找到系统的极限 ②负载测试&#xff1a;系统在极限工作条件下&#xff0c;最多能持续多久——可能发生内存泄漏/溢出&#xff0c;导…

angular技术(持续更新)

css类绑定[class.color-blue]"isBlue()" 如果isBlue()返回为true 这里使用color-blue的class样式style样式绑定[style.background-color]"canclick ? blue: red" 组件与模块模块的元数据*declarations: 用于指定属于这个模块的视图类&#xff08;View Cla…

CM6.3.2启用Kerberos(附问题解决)

基础准备支持JCE的jdk重新安装JCE的jdk(已正确配置跳过)删除/usr/java/下面的jdk,然后通过CM->管理->安全->安装Java无限制...重新安装后,配置Java(可选)主机->主机配置->搜java->Java主目录 配置路径主机->所有主机->设置->高级:Java配置Kerberos安…

[算法]插入排序

参考&#xff1a;《漫画算法-小灰的算法之旅》 目录 1、排序算法的思想 2、具体步骤 3、插入排序的优化 4、时间复杂度和空间复杂度 5、代码 1、排序算法的思想 维护一个有序区&#xff0c;把元素一个个插入有序区的适当位置&#xff0c;直到所有元素都有序为止。 2、具体…

多线程面试题

1. Sychronized的锁升级过程是怎样的&#xff1f; 2. Tomcat 中为什么要使用自定义类加载器&#xff1f; 3. 说说对线程安全的理解 4. 对守护线程的理解 5. 并发、并行、串行之间的区别 6. Java死锁如何避免&#xff1f; 7. 谈谈你对AQS的理解&#xff0c;AQS如何实现可重入锁&…

华为机试题:HJ107 求解立方根(python)

文章目录&#xff08;1&#xff09;题目描述&#xff08;2&#xff09;Python3实现&#xff08;3&#xff09;知识点详解1、input()&#xff1a;获取控制台&#xff08;任意形式&#xff09;的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…

2023年品牌惊蛰节气海报赏析

今天是3月6日——惊蛰&#xff0c;春日渐暖&#xff0c;春雷乍起&#xff0c;北方大地正在迎来新生&#xff0c;小鸟在枝头欢叫、种子在努力发芽&#xff0c;各大品牌也赶早发布了最新的惊蛰节气海报。下面就来和我们一起看看吧。 1&#xff0c;中国日报 2&#xff0c;BDuck…

java日志

日志是软件开发的重要组成部分。一个精心编写的日志代码提供快速的调试&#xff0c;维护方便&#xff0c;以及应用程序的运行时信息结构化存储。日志记录确实也有它的缺点。它可以减缓的应用程序Log4jLog4j是Apache的一个开放源代码项目&#xff0c;通过使用Log4j&#xff0c;我…

Spring | 基础

1. IOC和DI IOC&#xff1a;控制反转&#xff0c;其思想是反转资源获取的方向&#xff0c;传统的资源查找方式要求组件向容器发起请求查找资源&#xff0c;作为回应&#xff0c;容器适时的返回资源。而应用了 IOC 之后&#xff0c;则是**容器主动地将资源推送给它所管理的组件…

Sectigo中间证书根证书说明

Sectigo SSL证书产品证书链主要分为两个版本&#xff0c;常见的的一种版本多&#xff0c;但随着安全性提升&#xff0c;证书链的加载方式变化&#xff0c;第二种版本证书链更具备安全需要&#xff0c;对此做了详细说明。一、兼容性最高版本&#xff0c;根证书算法&#xff1a;s…

BI 是如何数据分析的?

企业部署商业智能BI前&#xff0c;需要进行详细的分析&#xff0c;了解BI能为企业带来多少价值&#xff1f;如何提高工作效率的等等&#xff0c;今天我们就来聊一聊 BI 的工作原理。 一、BI的取数方式 商业智能BI是通过访问和连接业务系统数据源数据库的方式来进行取数的&…

记录gitlab和jenkins集成的过程

gitlab设置外发请求 首先在前面的几篇文章中&#xff0c;我们的gitlab和jenkins都安装好了&#xff0c;在这里我们就可以对gitlab 和jenkins进行集成操作处理。 首先设置gitlab的外发请求,如图所示: 先点击管理员&#xff0c;进入到管理中心后 先点击设置&#xff0c;然后点击…

劲霸男装:400+门店的销售佣金管理,如何实现一键发薪

陪伴一代人记忆的劲霸男装&#xff08;下文简称「劲霸」&#xff09;&#xff0c;很多人应该都不陌生。 他们的门店遍布全国的大型商场及街边店铺&#xff0c;自1980起&#xff0c;发展已40余年&#xff0c;现拥有形象统一、规范管理的品牌专卖店2000多家。他们门店多&#xff…

传输层协议——UDP协议

❣️关注专栏&#xff1a;JavaEE 传输层虽然是操纵系统内核已经实现好了的&#xff0c;但是我们程序猿写代码要调用系统提供的 socket API 完成网络编程&#xff0c;其中 socket 就属于传输层部分。 &#x1f331; UDP协议 &#x1f331; 1 UDP协议端格式 上图就是UDP协议报…

Java面向对象特征之三:多态

一&#xff1a;面向对象三大特征之三&#xff1a;多态 1.多态是什么&#xff1f; 同类型的对象&#xff0c;执行同一个行为&#xff0c;会表现出不同的行为特征。 比如&#xff1a;猫和狗都是动物类型&#xff0c;执行同一个行为&#xff0c;但是会表现出不同的行为特征&…