問(wèn)題
某軟件要求湾盒,從網(wǎng)絡(luò)抓取各個(gè)城市氣溫信息埋哟,并依次展示
如果一次抓取所有城市天氣再顯示盖矫,顯示第一個(gè)城市氣溫時(shí)纽匙,
有很高的延時(shí)务蝠,并且浪費(fèi)存儲(chǔ)空間.我們期望以"用時(shí)訪問(wèn)"策略,
并且能把所有城市氣溫封裝到一個(gè)對(duì)象拍谐,可用for語(yǔ)句進(jìn)行的迭代烛缔,
如何解決馏段?
- 我們先來(lái)觀察一下我們?nèi)粘V杏玫降目傻鷮?duì)象他們之間的共性。
# -*- coding: utf-8 -*-
l = [1,2,3,4]
s = 'abcde'
## 確保in后面是一個(gè)可迭代對(duì)象
#由可迭代對(duì)象得到迭代器
for x in l:print x
for x in s:print x
# 使用iter可以將可迭代對(duì)象list變成一個(gè)迭代器對(duì)象
print iter(l)
print iter(s)
#此處傳入不可迭代對(duì)象將會(huì)拋出異常
# print iter(5)
#使用dir函數(shù)來(lái)查看當(dāng)前對(duì)象可以使用的方法:__為內(nèi)置方法
print dir(l)
print dir(s)
print iter(l)
#等價(jià)于list對(duì)象l調(diào)用了__iter__()
print l.__iter__()
#要么能支持一個(gè)迭代器践瓷,要么支持一個(gè)序列
#s.字符串對(duì)象不包含__iter__,但是它擁有__getitem__
print s.__getitem__(0)
#一個(gè)迭代器對(duì)象擁有哪些接口院喜?
#
print dir(iter(l))
# 可以看出它只有一個(gè)next方法。
t = iter(l)
print t.next()
print t.next()
print t.next()
print t.next()
# print t.next()
#次數(shù)一直調(diào)用next方法晕翠,直到拋出stop異常
通過(guò)上述探究可以發(fā)現(xiàn)可迭代對(duì)象必須擁有iter或getitem方法而喷舀。而迭代器對(duì)象則擁有next方法。
for循環(huán)內(nèi)部將l這個(gè)可迭代的對(duì)象使用iter()變成一個(gè)迭代器對(duì)象淋肾,
然后調(diào)用next()方法不斷取值硫麻,當(dāng)值全部遍歷完時(shí),拋出stopexception樊卓。
因此我們想實(shí)現(xiàn)一個(gè)可迭代對(duì)象需要兩步:
step1:實(shí)現(xiàn)迭代器對(duì)象WeatherIterator,next方法每次返回一個(gè)城市的氣溫
step2:實(shí)現(xiàn)一個(gè)可迭代對(duì)象拿愧,WeatherIterable,iter方法返回一個(gè)迭代器對(duì)象
import requests
# 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'])
# print getweather(u'北京')
# print getweather(u'長(zhǎng)春')
from collections import Iterable, Iterator
print Iterator.__abstractmethods__
print Iterable.__abstractmethods__
##直接繼承抽象類
class 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(seld.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)
for x in WeatherIterable([u'北京',u'上海',u'廣州',u'長(zhǎng)春']):
print x