17、Python与设计模式--迭代器模式

一、迭代器与生成器

今天的主角是迭代器模式。在python中,迭代器并不用举太多的例子,因为python中的迭代器应用实在太多了(不管是python还是其它很多的编程语言中,实际上迭代器都已经纳入到了常用的库或者包中)。而且在当前,也几乎没有人专门去开发一个迭代器,而是直接去使用list、string、set、dict等python可迭代对象,或者直接使用__iter__和next函数来实现迭代器。如下例:

if __name__=="__main__":
    lst=["hello Alice","hello Bob","hello Eve"]
    lst_iter=iter(lst)
    print lst_iter
    print lst_iter.next()
    print lst_iter.next()
    print lst_iter.next()
    print lst_iter.next()

打印如下:

hello Alice
hello Bob
hello Eve
Traceback (most recent call last):
File "D:/WorkSpace/Project/PyDesignMode/example.py", line 719, in
print lst_iter.next()
StopIteration
在这种迭代器的使用过程中,如果next超过了迭代范围,会抛出异常。
在python对象的方法中,也可以轻易使用迭代器模式构造可迭代对象,如下例:

class MyIter(object):
    def __init__(self, n):
        self.index = 0
        self.n = n
    def __iter__(self):
        return self
    def next(self):
        if self.index < self.n:
            value = self.index**2
            self.index += 1
            return value
        else:
            raise StopIteration()

__iter__和next实现了迭代器最基本的方法。如下方式进行调用:

if __name__=="__main__":
    x_square=MyIter(10)
    for x in x_square:
        print x

打印如下:
0
1
4
9
16
25
36
49
64
81
注意__iter__方法中的返回值,由于直接返回了self,因而该迭代器是无法重复迭代的,如以下业务场景:

if __name__=="__main__":
    x_square=MyIter(10)
    for x in x_square:
        print x
    for x in x_square:
        print x

只能打印一遍平方值。解决办法是,在__iter__中不返回实例,而再返回一个对象,写成:

def __iter__(self):
    return MyIter(self.n)

这样,在每次迭代时都可以将迭代器“初始化”,就可以多次迭代了。
另外,在python中,使用生成器可以很方便的支持迭代器协议。生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。
如下例:

def MyGenerater(n):
    index=0
    while index<n:
        yield index**2
        index+=1

注意,这是个函数。在每次调用生成器,得到返回结果后,现场得以保留,下次再调用该生 成器时,返回保留的现场从yield后继续执行程序。

if __name__=="__main__":
    x_square=MyGenerater(10)
    for x in x_square:
        print x

打印结果与上面一致。

二、迭代器模式

迭代器模式的定义如下:它提供一种方法,访问一个容器对象中各个元素,而又不需要暴露对象的内部细节。

时间: 2024-11-17 15:52:18

17、Python与设计模式--迭代器模式的相关文章

[Head First设计模式]生活中学设计模式——迭代器模式

系列文章 [Head First设计模式]山西面馆中的设计模式--装饰者模式 [Head First设计模式]山西面馆中的设计模式--观察者模式 [Head First设计模式]山西面馆中的设计模式--建造者模式 [Head First设计模式]饺子馆(冬至)中的设计模式--工厂模式 [Head First设计模式]一个人的平安夜--单例模式 [Head First设计模式]抢票中的设计模式--代理模式 [Head First设计模式]面向对象的3特征5原则 [Head First设计模式]鸭子

hand first设计模式 -迭代器模式

迭代器模式 : 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. A食物 Java代码 public class AFood { private String name; private double price; public AFood(String name,double price){ this.name= name; this.price = price; } public String getName() { return name; } public void

解读设计模式----迭代器模式(Iterator Pattern)

一.你在开发中使用过迭代吗? 当你在使用JavaScript开发客户端应用的时候使用过for...in吗? 1<script type="text/javascript"> 2var obj; 3useForIn = function () 4{ 5 obj = (0,1,2,3,4,5,6,7,8,9); 6 for(var o in obj) 7 { 8 document.write(o); 9 } 10} 11</script> 当你在.NET Frame

PHP设计模式——迭代器模式

声明:本系列博客参考资料<大话设计模式>,作者程杰.        迭代器模式:迭代器模式是遍历集合的成熟模式,迭代器模式的关键是将遍历集合的任务交给一个叫做迭代器的对象,它的工作时遍历并选择序列中的对象,而客户端程序员不必知道或关心该集合序列底层的结构.        UML类图:                  角色:               Iterator(迭代器):迭代器定义访问和遍历元素的接口         ConcreteIterator(具体迭代器):具体迭代器实现迭代

.NET设计模式-迭代器模式(Iterator Pattern)

概述 在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据.面向对象设计原则中有一条是类的单一职责原则,所以我们要尽可能的去分解这些职责,用不同的类去承担不同的职责.Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据. 意图 提供一种方法顺序访问一个聚合对象中

设计模式之禅之设计模式-迭代器模式

一:迭代器模式的定义        --->迭代器模式(Iterator Pattern)目前已经是一个没落的模式,基本上没人会单独写一个迭代器,除非是产品性质的开发        --->它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节.        --->迭代器是为容器服务的,那什么是容器呢? 能容纳对象的所有类型都可以称之为容器,例如Collection集合类型.Set类型等,迭代器模式就是为解决遍历这些容器中的元素而诞生的        --->迭

5、Python与设计模式--代理模式

一.网络服务器配置白名单 代理模式是一种使用频率非常高的模式,在多个著名的开源软件和当前多个著名的互联网产品后台程序中都有所应用.下面我们用一个抽象化的简单例子,来说明代理模式. 首先,构造一个网络服务器: #该服务器接受如下格式数据,addr代表地址,content代表接收的信息内容 info_struct=dict() info_struct["addr"]=10000 info_struct["content"]="" class Serv

4、Python与设计模式--原型模式

一.图层 大家如果用过类似于Photoshop的平面设计软件,一定都知道图层的概念.图层概念的提出,使得设计.图形修改等操作更加便利.设计师既可以修改和绘制当前图像对象,又可以保留其它图像对象,逻辑清晰,且可以及时得到反馈.本节内容,将以图层为主角,介绍原型模式. 首先,设计一个图层对象. class simpleLayer: background=[0,0,0,0] content="blank" def getContent(self): return self.content d

8、Python与设计模式--门面模式

一.火警报警器(1) 假设有一组火警报警系统,由三个子元件构成:一个警报器,一个喷水器,一个自动拨打电话的装置.其抽象如下: class AlarmSensor: def run(self): print "Alarm Ring..." class WaterSprinker: def run(self): print "Spray Water..." class EmergencyDialer: def run(self): print "Dial 11