IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 迭代器协议 及 python中强大的for循环机制 -> 正文阅读

[Python知识库]迭代器协议 及 python中强大的for循环机制

一、什么是迭代器协议

迭代器协议:是指,对象必须提供一个__next__()方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代。(只能往后走,不能往前退)
协议:是一种约定。可迭代对象实现了迭代器协议,python的内部工具,如for循环、sum函数、min函数、max函数等都是遵循迭代器协议访问对象。
可迭代对象:实现了迭代器协议的对象。(如何实现?对象内部定义了一个__iter__()方法)

二、python中强大的for循环机制

1、for循环的本质是什么?

for循环的本质,其实就是遵循迭代器协议去访问对象。然后在for循环的时候去调用 可迭代对象 内部的__next__()方法。

那么,列表、元组、字符串、字典、集合、文件对象是不是可迭代对象呢?答案是:否。

他们只不过是在for循环时,调用了他们内部的__iter__()方法把他们变成了可迭代对象

然后for循环,再调用可迭代对象内部的__next__()方法去取值,而且for循环会捕捉StopIteration异常,以终止迭代。

# 举例:
# 定义一个列表
L = [1, 2, 3, 4, 5]
# 每次for循环一次就先把列表变为可迭代对象,然后去调用可迭代对象L里的next()方法一次,去循环取值
for i in L:   # for循环相当于 L.__iter__().__next__()
	print(i)

具体步骤解析如下:

(1)查看列表的内置方法:

#! /usr/bin/env python
# -*- coding: utf-8 -*-

L = [1, 2, 3, 4, 5]
# 查看列表的内置方法
print(dir(L))

输出结果:(可看出,是没有__next__()方法的,所以不是可迭代对象)

['__add__', '__class__', '__contains__', '__delattr__', 
'__delitem__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__getitem__', 
'__gt__', '__hash__', '__iadd__', '__imul__', '__init__', 
'__init_subclass__', '__iter__', '__le__', '__len__', 
'__lt__', '__mul__', '__ne__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__reversed__', '__rmul__', 
'__setattr__', '__setitem__', '__sizeof__', '__str__', 
'__subclasshook__', 'append', 'clear', 'copy', 'count', 
'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 
'sort']

(2)调用了他们内部的__iter__()方法:

L = [1, 2, 3, 4, 5]

# 调用了列表内部的__iter__()方法,把列表变成了可迭代对象。
iter_test = L.__iter__()
print(iter_test)

输出的结果:(把列表变为可迭代对象)

<list_iterator object at 0x000001FC55F71788>

(3)此时再去调用可迭代对象的__next__()方法,就可以一个个取出值,调用一次取一个。

L = [1, 2, 3, 4, 5]
# 调用了列表内部的__iter__()方法,把列表变成了可迭代对象。
iter_test = L.__iter__()
# 调用可迭代对象iter_test 的__next__() 方法
print(iter_test.__next__())
print(iter_test.__next__())
print(iter_test.__next__())
print(iter_test.__next__())
print(iter_test.__next__())
# 第6次调用的时候,捕捉StopIteration异常
print(iter_test.__next__())

输出结果:

在这里插入图片描述

2、为什么要用for循环?

我们都知道,还有一种方法可以去循环遍历取值,那就是使用下标的方式去访问。但是只有序列类型对象,如字符串、列表、元组 才支持使用下标的方式去取值。

# 如果是列表、元组、字符串,可以用索要下标的方式去取值
L = [1, 2, 3, 4, 5]
index = 0
while index < len(L):
    print(L[index])
    index += 1

而集合、字典、文件对象,这样的非序列类型对象,是不支持使用下标的方式去访问的。

所以,for循环就基于迭代器协议提供了一个统一的可以遍历所有对象的方法,即,在遍历之前,先调用对象的__iter__()方法,把对象变成了可迭代对象(迭代器),然后使用迭代器协议去实现循环访问,这样所有的对象就都可以通过for循环来访问了。

# 用while 去模拟for 循环做的事情
dic = {1, 2, 3}
# 先调用对象的__iter__()方法,把对象转换为可迭代对象(迭代器)
dic_test = dic.__iter__()
while True:
    try:
        print(dic_test.__next__())  # 在遵循迭代器协议,去调用可迭代对象的__next__()方法,去取值
    except StopIteration:   # 捕获StopIteration异常,以停止迭代
        print("迭代完毕,循环截止了!")
        break
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 11:36:25  更:2021-07-25 11:38:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 0:10:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码