Python控制流程迭代对象迭代器生成器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python控制流程迭代对象迭代器生成器相关的知识,希望对你有一定的参考价值。
#14.1 Sentence类第一版,单词序列
#栗子14-1 吧句子划分为单词序列
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 __len__(self): #为了完善序列,我们实现__len__方法,为了让对象可迭代,没必要实现这个方法
return len(self.words)
def __repr__(self):
return ‘Sentence(%s)‘ % reprlib.repr(self.text) #生成大型数据结构的简略字符串表示
#栗子14-2 测试Sentence是否可迭代
s = Sentence(‘"The tiem has come,",the walrus said,‘)
print(s) #Sentence(‘"The tiem ha... walrus said,‘)
for word in s:
print(word)
‘‘‘
The
tiem
has
come
the
walrus
said
‘‘‘
print(list(s)) #[‘The‘, ‘tiem‘, ‘has‘, ‘come‘, ‘the‘, ‘walrus‘, ‘said‘]
#【分析】序列可迭代的原因
‘‘‘
(1)检查内置对象是否实现了__iter__方法,如果实现了就调用他,获取一个迭代器
(2)如果没有实现__iter__方法,但是实现了__getitem__方法,Python会创建一个迭代器,尝试按顺序(从索引0开始)获取元素
(3)如果尝试失败,Python跑出TypeError异常,通常会提示"C object is not itrable"
‘‘‘
#14.2 可迭代对象和迭代器对比
# Iterable 和 Iterator 抽象基类。前者是后者的父类,后者在前者__iter__的基础上,新加了__next__方法。
#Iterator 里有个方法
import abc
@classmethod
def __subclasshook__(cls,C):
if cls is abc.Iterator:
if (any("__next__" in B.__dict__ for B in C.__mro__) and
any("__iter__" in B.__dict__ for B in C.__mro__)):
return True
return NotImplemented
#考虑到Lib/types.py中的建议,以及Lib/_collections_abc.py中的逻辑实现,检查对象x是否为迭代器最好的方式是调用isinstance(x,abc.Iterator)。得益于Iterator.__subclasshook__方法,即使对象x
#...所属的类不是Iterator类的真实子类或者虚拟子类,也能这么检查
#使用栗子14-1 中的类,用iter()函数构建迭代器,用next()函数使用迭代器
s3 = Sentence(‘Pig and Pepper‘)
it = iter(s3)
print(it) #<iterator object at 0x0000000002948A58>
print(next(it)) #Pig
print(next(it)) #and
print(next(it)) #Pepper
#print(next(it)) #StopIteration
print(list(it)) #[] 到头后,迭代器没用了
print(list(iter(s3))) #[‘Pig‘, ‘and‘, ‘Pepper‘] 要想再次迭代,要重新构建迭代器
#因为内置的 iter(...) 函数会对序列做特殊处理,所以第 1 版 Sentence 类可以迭代。接下来要实现标准的可迭代协议
以上是关于Python控制流程迭代对象迭代器生成器的主要内容,如果未能解决你的问题,请参考以下文章