3-1 如何实现可迭代对象和迭代器对象

基础复习:
可迭代对象:满足了迭代协议的一个接口__iter__或者 __getitem__

迭代器对象:满足了迭代协议的__next__接口

__next__:可以得到迭代器中的下一个元素,最后一个元素被取出后,会抛出StopIteration异常

for循环工作机制:
1 由iter()方法得到一个迭代器
2.不停地调用next()方法,直到捕获一个StopIteration异常,退出循环

iter(...)
    iter(iterable) -> iterator
    iter(callable, sentinel) -> iterator

    Get an iterator from an object.  In the first form, the argument must
    supply its own iterator, or be a sequence.
    In the second form, the callable is called until it returns the sentinel.
# 可以由可迭代对象得到一个迭代器
l = [1,2,3,4]
print(iter(l)) # 
print(l.__iter__()) # 

问题抛出:
如何实现可迭代对象和迭代器对象

实际案例:
某软件要求,从网络抓取各个城市的气温信息,并以此显示:
北京:15-20
天津:17-22
长春:12-18
....
如果一次抓取所有的城市天气再显示,显示第一个城市气温时,有很高的延时,并且浪费存储空间。
我们期望以“用时访问”策略,并且能把所有的城市气温封装到一个对象里,可用for语句进行迭代,如何解决?

解决方案:
1.实现一个迭代器对象WeatherIterator,next方法每次返回一个气温
2.实现一个可迭代对象WeatherIterable,iter方法返回一个迭代器对象

import requests
from collections import Iterable,Iterator

class WeatherIterator(Iterator):
    """
    迭代器对象,满足__next__接口
    """
    def __init__(self,citys):
        self.citys = citys
        self.index = 0

    def _getCityWeather(self,city):
        r = requests.get("http://wthrcdn.etouch.cn/weather_mini?city=%s" % city)
        data = r.json()['data']['forecast'][0]
        return "%s:%s-%s" % (city, data['low'], data['high'])

    def __next__(self):
        if self.index == len(self.citys):
            raise StopIteration
        city = self.citys[self.index]
        self.index += 1
        return self._getCityWeather(city)

class WeatherIterable(Iterable):
    """
    可迭代对象,满足__iter__接口
    """
    def __init__(self,citys):
        self.citys = citys

    def __iter__(self):
        return WeatherIterator(self.citys)

citys = ['北京', '上海', '广州', '深圳']
weather_obj = WeatherIterable(citys)

for x in weather_obj:
    print(x)

"""
北京:低温 -6℃-高温 4℃
上海:低温 5℃-高温 11℃
广州:低温 14℃-高温 22℃
深圳:低温 16℃-高温 23℃
"""

你可能感兴趣的:(3-1 如何实现可迭代对象和迭代器对象)