迭代器:例如 列表
迭代器模式
提供了一种方法能够顺序访问集合中的所有元素,而又不暴露集合内部的实现
迭代器的本质是实现了一种方式:
能够判断集合中是否还有未被访问的元素,以及提供访问这个元素的方式
代码实例
# -*- coding: utf-8 -*-
# @File : 迭代器模式.py
# @Date : 2018-05-23
from abc import abstractmethod
# 定义迭代器
# 实现了两个方法,是否还有未被访问的元素和下一个未被访问的元素
class Iterator(object):
def __init__(self):
pass
@abstractmethod
def has_next(self):
pass
@abstractmethod
def next(self):
pass
# 一个书架上摆满了书,我们需要查找某本书时,就用到了迭代器模式
# 定义书本, 名称和编号
class Book(object):
def __init__(self, name, number):
self.name = name
self.number = number
# 书架定义
# 书架实现了增加书目,查找index位置的数目以及总共的图书数目这几个方法
class BookShelf(object):
def __init__(self):
self.books = []
def append_book(self, book):
self.books.append(book)
def get_book_at(self, index):
return self.books[index]
def get_length(self):
return self.books.__len__()
# Iterator的具体实现
class BookShelfIterator(Iterator):
def __init__(self, book_shelf):
self.book_shelf = book_shelf
self.index = 0
def has_next(self):
if self.index < self.book_shelf.get_length():
return True
else:
return False
def next(self):
book = self.book_shelf.get_book_at(self.index)
self.index += 1
return book
if __name__ == "__main__":
book_shelf = BookShelf()
book_shelf.append_book(Book("语文", "001"))
book_shelf.append_book(Book("数学", "002"))
book_shelf.append_book(Book("英语", "003"))
book_shelf_iterator = BookShelfIterator(book_shelf)
# 通过hasNext方法和next方法便可以访问数目的具体信息
while book_shelf_iterator.has_next():
book = book_shelf_iterator.next()
print(book.name, book.number)
"""
语文 001
数学 002
英语 003
"""
python实现迭代器
任何实现了__iter__
和__next__
方法的对象都是迭代器
__iter__
返回迭代器自身
__next__
返回容器中的下一个值
Python3
# 新书架python实现
class NewBookShelf(BookShelf):
def __init__(self):
self.index = 0
BookShelf.__init__(self)
# 实现容器,进行成员检查
def __contains__(self, book):
if book in self.books:
return True
else:
return False
# 可迭代对象实现了__iter__方法
def __iter__(self):
return self
# 迭代器实现next方法
def __next__(self):
if self.index < self.get_length():
book = self.books[self.index]
self.index += 1
return book
else:
raise StopIteration # 停止标志
if __name__ == "__main__":
# 新书架
new_book_shelf = NewBookShelf()
book1 =Book("语文", "001")
new_book_shelf.append_book(book1)
new_book_shelf.append_book(Book("数学", "002"))
new_book_shelf.append_book(Book("英语", "003"))
# 成员检查
print(book1 in new_book_shelf)
# True
# 迭代书本
for book in new_book_shelf:
print(book.name, book.number)
"""
语文 001
数学 002
英语 003
"""
Python2
# 新书架python实现
class NewBookShelf(BookShelf):
def __init__(self):
self.index = 0
BookShelf.__init__(self)
# 实现容器,进行成员检查
def __contains__(self, book):
if book in self.books:
return True
else:
return False
# 可迭代对象实现了__iter__方法
def __iter__(self):
return self
def next(self):
if self.index < self.get_length():
book = self.books[self.index]
self.index += 1
return book
else:
raise StopIteration # 停止标志
Python3 和 Python2和 略有不同,Python3 使用 __next__
替换了 next
会报错
TypeError: iter() returned non-iterator of type 'NewBookShelf'
所以可以写个兼容代码
# 新书架python实现
class NewBookShelf(BookShelf):
def __init__(self):
self.index = 0
BookShelf.__init__(self)
# 实现容器,进行成员检查
def __contains__(self, book):
if book in self.books:
return True
else:
return False
# 可迭代对象实现了__iter__方法
def __iter__(self):
return self
# 兼容 Python3 和 Python2
def next(self):
return self.__next__()
# 迭代器实现next方法
def __next__(self):
if self.index < self.get_length():
book = self.books[self.index]
self.index += 1
return book
else:
raise StopIteration # 停止标志
总结
概念 | 实现 |
---|---|
容器(container) | __contains__ |
可迭代对象(iterable) | __iter__ 返回迭代器自身 |
迭代器(iterator) | __next__ 返回容器中的下一个值 停止标志StopIteration |
生成器(generator) | yiled关键字 |
生成器表达式(generator expression) | [x for x in lst ] -> (x for x in lst) |
参考: