Python-for循环的内部机制


Posted in Python onJune 12, 2020

Python中,使用for循环可以迭代容器对象中的元素,这里容器对象包括是列表(list)、元组(tuple)、字典(dict)、集合(set)等。但是,为什么这些对象可以使用for循环进行操作呢?

首先,定义一个简单的类尝试一下:

class TestRange:
  def __init__(self, num):
    self.num = num
for i in TestRange(10):
  print(i)

# 输出
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'TestRange' object is not iterable

错误信息提示,'TestRange' object 不是可迭代的对象。那么,什么才是可迭代的对象呢?

在可迭代的对象中,需要实现一个__iter__魔法方法,而且这个方法的返回值需要是一个迭代器。那么,什么是迭代器呢?

迭代器只需要实现__next__魔法方法。

以列表(list)为例:

>>> nums = [13,12,33]
>>> iter_ret = nums.__iter__() # x有此方法,说明list是可迭代的,而且该方法返回一个迭代器
>>> iter_ret
<list_iterator object at 0x100f32198>

>>> iter_ret.__next__()
13
>>> iter_ret.__next__()
12
>>> iter_ret.__next__()
33
>>> iter_ret.__next__()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration

分析:

如上所示,列表nums中实现了__iter__方法,而且返回一个迭代器(iterator),迭代器中实现了__next__方法。在不断调用__next__的过程中,就是在不断返回nums中的元素,直到出现StopIteration的错误。

其实,for语句的作用与此类似。for语句的内部机制为

  • 先判断对象是否为可迭代对象,即是否存在__iter__方法,如果存在则调用__iter__方法,返回一个迭代器;否则,直接抛出TypeError异常;
  • 不断地调用迭代器的__next__方法,每次调用按顺序迭代获取当前的值;
  • 迭代完所有元素,就抛出异常 StopIteration,这个异常 python 解释器自己会处理;

前面的 TestRange 报错是因为它没有实现迭代器协议里面的这两个方法,现在继续改进:

class TestRange:
  def __init__(self, _max):
    self.i = 0
    self._max = _max

  def __iter__(self):
    return self

  def __next__(self):
    if self.i < self._max:
      i = self.i
      self.i += 1
      return i
    else:
      # 达到停止条件时,抛出此异常
      raise StopIteration()

# 进行测试
for i in TestRange(3):
  print(i)
# 输出
 0
 1
 2

分析:

因为这个类中,已经实现了__next__方法,所以基于这个类所创建的对象,本身就是一个迭代器。又因为可迭代对象需要有__iter__方法,而且返回一个迭代器,所以__iter__返回对象本身self即可。

总结

到此这篇关于Python-for循环的内部机制的文章就介绍到这了,更多相关python for 循环内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
跟老齐学Python之传说中的函数编写条规
Oct 11 Python
纯python实现机器学习之kNN算法示例
Mar 01 Python
python 将列表中的字符串连接成一个长路径的方法
Oct 23 Python
pygame游戏之旅 按钮上添加文字的方法
Nov 21 Python
Linux 修改Python命令的方法示例
Dec 03 Python
Python+AutoIt实现界面工具开发过程详解
Aug 07 Python
python网络编程之多线程同时接受和发送
Sep 03 Python
Python生成验证码、计算具体日期是一年中的第几天实例代码详解
Oct 16 Python
Python PyPDF2模块安装使用解析
Jan 19 Python
python中count函数简单的实例讲解
Feb 06 Python
Python爬虫回测股票的实例讲解
Jan 22 Python
python中threading和queue库实现多线程编程
Feb 06 Python
Python Scrapy图片爬取原理及代码实例
Jun 12 #Python
Python Scrapy多页数据爬取实现过程解析
Jun 12 #Python
Selenium自动化测试工具使用方法汇总
Jun 12 #Python
Python使用socketServer包搭建简易服务器过程详解
Jun 12 #Python
Django之腾讯云短信的实现
Jun 12 #Python
python相对企业语言优势在哪
Jun 12 #Python
keras实现基于孪生网络的图片相似度计算方式
Jun 11 #Python
You might like
PHP乱码问题,UTF-8乱码常见问题小结
2012/04/09 PHP
php中jQuery插件autocomplate的简单使用笔记
2012/06/14 PHP
PHP设计模式之策略模式原理与用法实例分析
2019/04/04 PHP
jquery实现多行文字图片滚动效果示例代码
2014/10/10 Javascript
javascript上下方向键控制表格行选中并高亮显示的方法
2015/02/13 Javascript
HTML5实现留言和回复页面样式
2015/07/22 Javascript
jQuery EasyUI实现右键菜单变灰不可用效果
2015/09/24 Javascript
Node.js巧妙实现Web应用代码热更新
2015/10/22 Javascript
js阻止浏览器默认行为的简单实例
2016/05/15 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
2016/05/20 Javascript
浅谈几种常用的JS类定义方法
2016/06/08 Javascript
vue + axios get下载文件功能
2019/09/25 Javascript
基于Vue 撸一个指令实现拖拽功能
2019/10/09 Javascript
使用js获取身份证年龄的示例代码
2020/12/11 Javascript
python遍历类中所有成员的方法
2015/03/18 Python
python 写入csv乱码问题解决方法
2016/10/23 Python
Python IDLE 错误:IDLE''s subprocess didn''t make connection 的解决方案
2017/02/13 Python
Python模拟随机游走图形效果示例
2018/02/06 Python
python读取图片任意范围区域
2019/01/23 Python
详解Python爬取并下载《电影天堂》3千多部电影
2019/04/26 Python
对Python 简单串口收发GUI界面的实例详解
2019/06/12 Python
python将字符串转换成json的方法小结
2019/07/09 Python
python+opencv像素的加减和加权操作的实现
2019/07/14 Python
python如何查看网页代码
2020/06/07 Python
浅谈Python 参数与变量
2020/06/20 Python
javascript实现用户必须勾选协议实例讲解
2021/03/24 Javascript
通息工程毕业生自荐信
2013/10/16 职场文书
老师自我鉴定范文
2013/12/25 职场文书
培训班主持词
2014/03/28 职场文书
租房协议书样本
2014/08/20 职场文书
二手车转让协议书
2015/01/29 职场文书
2015年客服工作总结范文
2015/04/02 职场文书
创业计划书之校园跑腿公司
2019/09/24 职场文书
Python数据清洗工具之Numpy的基本操作
2021/04/22 Python
教你用Python matplotlib库制作简单的动画
2021/06/11 Python
python中 .npy文件的读写操作实例
2022/04/14 Python