
实际用例:
从网络抓取各个城市气温信息,并依次显示:
北京:15~20
天津:17~22
长春:12~18
.....
如果依次抓取所有城市天气再显示,显示第一个城市气温时,有很高的延时,
并且浪费存储空间.我们期望以"用时访问"的策略,并且能把所有城市气温封装到一个对象里,
可用for语句进行迭代.
解决方案:
step1:实现一个迭代器对象WeatherIterator,next方法每次返回一个城市气温
step2:实现一个可迭代对象WeatherIterable,__iter__方法返回一个迭代器对象.
如果你对迭代器和可迭代对象还不是太了解可以查看下面这篇文章
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# -*- coding: utf-8 -*- import requests __author__ = 'songhao' def 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']) if __name__ == '__main__': print(getweather("新乡")) # 返回的结果是: 新乡: 低温 5℃ , 高温 19℃ |
今天就利用可迭代对象,迭代器对象进行改写函数;
1 2 3 4 5 6 7 8 |
In [24]: from collections import Iterable,Iterator In [25]: Iterable.__abstractmethods__ Out[25]: frozenset({'__iter__'}) 可迭代对象的抽象接口就是__iter__' In [26]: Iterator.__abstractmethods__ Out[26]: frozenset({'__next__'}) 迭代器的抽象接口就是__next__ |

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
</pre> <pre># -*- coding: utf-8 -*- import requests from collections import Iterable, Iterator __author__ = 'songhao' ''' def 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']) ''' class Weather_Iterator(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 Weather_Iterator(self.cities) if __name__ == '__main__': for x in WeatherIterable(['新乡', '广州', '北京', '上海']): print(x) print('*'*50) for x in Weather_Iterator(['新乡', '广州', '北京', '上海']): print(x) """ ➜ bd python3 d7.py 新乡: 低温 4℃ , 高温 14℃ 广州: 低温 20℃ , 高温 24℃ 北京: 低温 -4℃ , 高温 8℃ 上海: 低温 13℃ , 高温 17℃ ************************************************** 新乡: 低温 4℃ , 高温 14℃ 广州: 低温 20℃ , 高温 24℃ 北京: 低温 -4℃ , 高温 8℃ 上海: 低温 13℃ , 高温 17℃ """ |
总结
实现for循环迭代关键两点:
一,__iter__()
二,__next__()
实例的末尾 for x in WeatherIterable([u'北京',u'上海',u'广州',u'咸宁']),其实可以直接用WeatherIterator([u'北京',u'上海',u'广州',u'咸宁'])替代,一样可以得出正确的结果。因为WeatherIterator继承了Iterator,因此就算WeatherIterator没有定义__iter__()方法,但是默认调用了父类Iterator的__iter()__方法,把可迭代对象参数变成迭代器参数,再调用定义好的__next__()。
帮助信息
Iterator迭代器:__iter__():__next__():
任何具有__next__()
方法的对象都是迭代器,对迭代器调用next()方法可以获取下一个值。
Iterable可迭代对象:
大部分容器都是可迭代的,但是还有其他一些对象也可以迭代,例如:文件对象以及管道对象等等,容器一般来说存储的元素是有限的
可迭代对象可以为任意对象,不一定非得是基本数据结构,只要这个对象可以返回一个iterator。
