python 中内置的可迭代的对象有 list、tuple、set、dict 等,那么我们自己怎么定义一个可迭代的对象呢?先来段代码吧

import re

import reprlib

RE_WORD = re.compile('\w+')

class Sentence:

def __init__(self, text):

self.text = text

self.words = RE_WORD.findall(text)

def __getitem__(self, item):

return self.words[item]

def __iter__(self):

for word in self.words:

yield word

sen = Sentence("abc def 123 456")

for i in sen:

print(i)

运行这段代码,结果如下:

E:\python36\python3.exe E:/python_demo/test1.py

abc

def

123

456

Process finished with exit code 0`

通过结果分析,我们已经看出 Sentence 对象已经是可迭代的了!

此时我们可以注释掉 iter 函数

class Sentence:

def __init__(self, text):

self.text = text

self.words = RE_WORD.findall(text)

def __getitem__(self, item):

return self.words[item]

# def __iter__(self):

# for word in self.words:

# yield word

再次运行发现结果正常,接着注释 __getitem__ 函数

class Sentence:

def __init__(self, text):

self.text = text

self.words = RE_WORD.findall(text)

# def __getitem__(self, item):

# return self.words[item]

# def __iter__(self):

# for word in self.words:

# yield word

发现报错了,报错信息很明朗,提示 Sentence 不是可迭代的对象

Traceback (most recent call last):

File "E:/python_demo/fluency_python/chapter14/test1.py", line 21, in

for i in sen:

TypeError: 'Sentence' object is not iterable

Process finished with exit code 1

看到这,是不是可以说,对象只需要实现 getitem 函数,那么该对象就是可迭代的呢?先别下定论,我们接着放开注释掉的 iter 函数

class Sentence:

def __init__(self, text):

self.text = text

self.words = RE_WORD.findall(text)

# def __getitem__(self, item):

# return self.words[item]

def __iter__(self):

for word in self.words:

yield word

发现运行结果又正确了,我们发现 __iter__ 和 __getitem__ 中实现任意一个,对象就是可迭代的,怎么解释这种情况呢,Python 解释器中有这样的描述

解释器需要迭代对象 x 时, 会自动调用 iter(x)。

内置的 iter 函数有以下作用。

检查对象是否实现了 __iter__方法, 如果实现了就调用它, 获取一个迭代器。

如果没有实现 __iter__方法, 但是实现了 __getitem__ 方法,Python 会创建一个迭代器, 尝试按顺序(从索引 0 开始) 获取元素。

如果尝试失败, Python 抛出 TypeError 异常, 通常会提示“C object is not iterable”(C 对象不可迭代) , 其中 C 是目标对象所属的类。

任何 Python 序列都可迭代的原因是, 它们都实现了 __getitem__ 函数。 其实, 标准的序列都实现了 __iter__ 函数, 因此你也应该这么做。

总结

因此我们在自定义可迭代对象需要实现__iter__函数

严格来讲,我们还需要实现 __getitem__函数,这个函数的主要作用是当前对象可通过下标取值

另外,如果有一个未知的对象,我们怎么判断该对象是否可迭代呢,两种方式:

iter(x)

这是最准确的判断方式,传入要判断的对象,只要对象实现了__getitem__ 、 __iter__中的其中一个,该对象都是可迭代的,否则抛出TypeError: 'C' object is not iterable 异常;这儿有个区别,如果仅仅实现了 getitem ,调用 iter(x) 返回的是迭代器对象,如果实现的是 iter ,那么调用 iter(x) 返回的是生成器对象;

isinstance(x, abc.Iterable)

该方式会自动忽略 getitem 函数,仅当对象实现了 iter 函数才返回 True,其他一律返回 False

python中对象不可迭代_【转】Python中自定义可迭代对象相关推荐

  1. 无法从套接字中获取更多数据_数据科学中应引起更多关注的一个组成部分

    无法从套接字中获取更多数据 介绍 (Introduction) Data science, machine learning, artificial intelligence, those terms ...

  2. python一切皆对象的理解_在 Python 中万物皆对象

    在 Python 中一切都是对象,并且几乎一切都有属性和方法.所有的函数都有一个内置的 __doc__ 属性,它会返回在函数源代码中定义的 doc string:sys 模块是一个对象,它有一个叫作 ...

  3. python中response对象的属性_关于python:AttributeError:’HTTPResponse’对象没有属性’split’...

    我正在尝试从Google财经获取一些信息,但出现此错误 AttributeError: 'HTTPResponse' object has no attribute 'split' 这是我的pytho ...

  4. python中nonetype指什么_关于python:什么是’NoneType’对象?

    当我运行python脚本时,我得到了这个错误: TypeError: cannot concatenate 'str' and 'NoneType' objects 我很确定"str&quo ...

  5. python中基本程序结构_关于Python 程序格式框架的描述,正确的是( )

    [判断题]元组的元素是可读的,可以对元组进行更新.增加.删除操作. [多选题]哪些选项关于循环结构的描述是正确的( ) [单选题]以下可以终结一个循环的是 . [判断题]对于大量列表的连接,exten ...

  6. python 参数类型的多态_【Python】面向对象:类与对象\封装\继承\多态

    六.Python面向对象--类与对象\封装\继承\多态 1.什么是面向对象编程 1.1 程序设计的范式:程序可控,易于理解 1.2 抽象并建立对象模型 1.3 程序是不同对象相互调用的逻辑.每个对象在 ...

  7. python处理数据的包_在Python中利用Into包整洁地进行数据迁移的教程

    动机 我们花费大量的时间将数据从普通的交换格式(比如CSV),迁移到像数组.数据库或者二进制存储等高效的计算格式.更糟糕的是,许多人没有将数据迁移到高效的格式,因为他们不知道怎么(或者不能)为他们的工 ...

  8. python之禅怎么关闭_《Python之禅》中对于Python编程过程中的一些建议

    围绕一门语言,学习它的文化精髓,能让你成为一名更优秀的程序员.如果你还没读过Python之禅(Zen of Python) ,那么打开Python的命令提示符输入import this,列表中的每一项 ...

  9. python文本结构化处理_在Python中标记非结构化文本数据

    python文本结构化处理 Labelled data has been a crucial demand for supervised machine learning leading to a n ...

  10. python中result的用法_关于Python中的列表理解及用法

    在Python中,列表理解通常用于编写单行语句,这些语句通过可迭代对象进行迭代以创建新的列表或字典.本文首先介绍for循环如何在Python中工作,然后解释如何在Python中使用列表理解. Pyth ...

最新文章

  1. NavReady的使用
  2. 原创 Reflector 8.1 反激活
  3. 打开老工程的办法(日常操作以这个为准)
  4. jdk类加载器执行步骤_[JDK 11] jcmd中的类加载器层次结构详细信息
  5. python操作windows库_python大佬养成计划----win下对数据库的操作
  6. conn.execute
  7. Android-消息机制总结
  8. 唐山职业技术学院计算机专业分数线,唐山职业技术学院历年分数线 2021唐山职业技术学院录取分数线...
  9. 自动化测试——接口测试——pandas——CSV文件参数化——数据驱动
  10. php中execute函数,PHP:调用布尔值上的成员函数execute()
  11. AGC005_E Sugigma The Showdown
  12. 动态库动态调用WEbservice的问题!
  13. 软件项目管理(SPM)课程总结及感想
  14. 富文本编辑器 froala-editor
  15. 一文理清集成运算放大器 ---- 总结篇
  16. centos php ioncube_如何在CentOS 7中安装ionCube Loader
  17. Python华氏摄氏度的转换
  18. 经典管理学定律4 - 鲶鱼效应
  19. 一文看懂财务数据的分析方法
  20. 【网络安全培训】无线局域网的安全威胁都有哪些?

热门文章

  1. 经验:一个普通的二本学生如何拿到大厂的offer?
  2. axios下载大文件_用Vue构建一个github“可视化大数据平台”
  3. js获取class里面的内容
  4. 探索“AI+算力”:加速创新与增长的无限潜力
  5. Java常用加密解密核心算法
  6. 五大主流浏览器四大内核(浏览器兼容)
  7. 【华东交大】计算机网络实验六
  8. 深度神经网络训练的必知技巧
  9. 手写Promise-最终篇
  10. 一个新的项目:狼人杀(二)