所有的生成器都是迭代器;
从可迭代的对象中获取迭代器
一、序列可迭代的原因:iter
函数
迭代对象x时,自动调用
iter(x)
- 检查是否实现
__iter__
方法,返回一个迭代器。 - 没有实现则,
__getitem__
方法(参数从0开始),创建一个迭代器,尝试按顺序获取元素。 - 如果失败,抛出TypeError异常,
"C object is not iterable"
从Python3.4开始,检查对象能否迭代最准确的方法是调用iter(x)函数,不过没有必要吧。
二、可迭代的对象与迭代器
标准的迭代器接口有两个方法:
- 无参
__next__
方法, 返回下一个可用元素,否则抛出StopIteration
异常 -
__iter__
返回self
,以便于在使用可迭代对象的地方使用迭代器,例如for循环
经典迭代器
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 __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
def __iter__(self):
return SentenceIterator(self.words)
class SentenceIterator:
def __init__(self, words):
self.words = words
self.index = 0
def __next__(self):
try:
word = self.words[self.index]
except IndexError:
raise StopIteration()
self.index += 1
return word
def __iter__(self):
return self
可迭代对象一定不能是自身的迭代器(可迭代对象必须实现iter方法,但不能实现迭代器)
三、生成器函数简化经典迭代器
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 __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
def __iter__(self):
for word in self.words:
yield word
# return
函数返回值。生成器函数返回生成器。生成器产出或生成值。
四、惰性实现
import re
import reprlib
RE_WORD = re.compile('\w+')
class Sentence:
def __init__(self, text):
self.text = text
def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
def __iter__(self):
for match in RE_WORD.finditer(self.text):
yield match.group()
# return
五、生成器表达式
import re
import reprlib
RE_WORD = re.compile('\w+')
class Sentence:
def __init__(self, text):
self.text = text
def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
def __iter__(self):
return(match.group() for match in RE_WORD.finditer(self.text))
六、关于生成器的更多内容
生成器也可以用来生成不受数据源限制的值。
标准库中的生成器函数
Python 3.3 新增 yield from 代替循环,还有...