案列:
某软件要求,从网络抓取各个城市气温信息,并依次显示:
北京:15-20
天津:17-22
长春:12-18
..........
如果一次抓取所有城市气温再显示,显示第一个城市气温时,有很高的延时,并且浪费存储空间。我们期望以'用时访问'的策略,并且能把所有城市气温封装到一个对象里,可用for语句进行进行迭代,如何解决?
import requests
from collections import Iterable, Iterator #从标准库collections中导入可迭代的模块和迭代器模块
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) #requests模块爬取网页上每个城市的天气信息
data = r.json()['data']['forecast'][0] #转化为json字典格式
return '%s:%s,%s' %(city,data['low'],data['high']) #返回格式化字符串内容
def __next__(self): #定义__next__接口触发迭代对象方法,每调用一次就迭代一个城市气温
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): #定义迭代器接口__iter__方法,实现可迭代对象,for循环自动触发
return WeatherIterator(self.cities) #返回获取天气的类
for x in WeatherIterable([u'北京',u'上海',u'广州',u'长春']):
print(x)
案例:
实现一个可迭代对象的类,它能迭代出给定范围内所有的质(素)数:
class PrimeNumbers:
def __init__(self,start,end):
self.start = start
self.end = end
def isPrimeNum(self,k): #定义筛选数字是否为质数的方法,不符合条件都返回假
if k < 2:
return False
for i in range(2,k):
if k % i == 0:
return False
return True
def __iter__(self): #定义迭代器接口__iter__方法,实现可迭代对象,for循环自动触发
for k in range(self.start,self.end):
if self.isPrimeNum(k):
yield k #yield作用在于每次迭代对象时返回了当前对象结果,等待下个对象进行迭代时就从当前对象基础上继续运行,相当于实现了__next__方法依次迭代
for x in PrimeNumbers(1,100):
print(x)