如何实现可迭代对象和迭代器对象

来源:互联网 发布:linux broken pipe 编辑:程序博客网 时间:2024/05/22 02:00

案例:

从网络抓取城市气温信息,依次显示:

北京:15~20

上海:17~22

成都:12~18

1.抓取所有信息存入字典

2.迭代字典,逐条显示

存在的问题:

若一次抓取所有城市天气再显示,显示首个城市气温时,延时很高,并且浪费存储空间。

解决思路:

采用“用时访问”的策略,抓一条,显示一条,将所有城市的气温封装在一个对象里,可以用for语句迭代。

迭代显示:

In [1]: l = [1,2,3,4]In [2]: s = 'abcde'In [3]: for x in l: print x1234In [4]: for x in s: print xabcde

内置函数iter,得到迭代器对象
由可迭代对象,得到迭代器
iter(l)实际上内部调用了l.__iter__()

In [5]: iter?Docstring:iter(collection) -> iteratoriter(callable, sentinel) -> iteratorGet an iterator from an object.  In the first form, the argument mustsupply its own iterator, or be a sequence.In the second form, the callable is called until it returns the sentinel.Type:      builtin_function_or_methodIn [7]: iter(l)Out[7]: <listiterator at 0xfa6a90>In [8]: iter(s)Out[8]: <iterator at 0xfa69d0>In [9]: iter(5)---------------------------------------------------------------------------TypeError                                 Traceback (most recent call last)<ipython-input-9-8559c94ab208> in <module>()----> 1 iter(5)TypeError: 'int' object is not iterableIn [10]: l.__l.__add__           l.__getslice__      l.__new__l.__class__         l.__gt__            l.__reduce__l.__contains__      l.__hash__          l.__reduce_ex__l.__delattr__       l.__iadd__          l.__repr__l.__delitem__       l.__imul__          l.__reversed__l.__delslice__      l.__init__          l.__rmul__l.__doc__           l.__iter__          l.__setattr__l.__eq__            l.__le__            l.__setitem__l.__format__        l.__len__           l.__setslice__l.__ge__            l.__lt__            l.__sizeof__l.__getattribute__  l.__mul__           l.__str__l.__getitem__       l.__ne__            l.__subclasshook__In [10]: l.__iter__()Out[10]: <listiterator at 0xfa6e10>In [11]: iter(l)Out[11]: <listiterator at 0xfa6cd0>In [12]: t = iter(l)In [13]: t.next()Out[13]: 1In [14]: t.next()Out[14]: 2In [15]: t.next()Out[15]: 3In [16]: t.next()Out[16]: 4In [17]: t.next()---------------------------------------------------------------------------StopIteration                             Traceback (most recent call last)<ipython-input-17-3660e2a3d509> in <module>()----> 1 t.next()StopIteration: 


解决方案:

step1:实现一个迭代器对象WeatherIterator, next方法每次返回一个城市气温

step2:实现一个可迭代对象Weatheriterable, __iter__方法返回一个迭代器对象

#coding:utf8import requestsdef getWeather(city):    r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?city=' + city)    data = r.json()['data']['forecast'][0]    return '%s: %s, %s' %(city,data['low'],data['high'])#[u'北京',u'上海',u'广州',u'长春']print getWeather(u'北京')print getWeather(u'长春')print getWeather(u'贺兰')

定义构造器

def __init__()

新建测试用例,for循环进行迭代

#coding:utf8import requests
from collections import Iterable,Iteratorclass WeatherIterator(Iterator): def __init__(self,cities): self.cities = cities self.index = 0 def getWeather(self, city): r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?city=' + city) data = r.json()['data']['forecast'][0] return '%s: %s, %s' %(city,data['low'],data['high']) def next(self): if self.index == len(self.cities): raise StopIteration city = self.cities[self.index] self.index += 1 return self.getWeather(city)class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities)#[u'北京',u'上海',u'贺兰',u'成都']for x in WeatherIterable([u'北京', u'上海',u'贺兰',u'成都']): print x




0 0
原创粉丝点击