zoukankan      html  css  js  c++  java
  • 从一个实际小例子来看python中迭代器的应用

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

    需求实现:
    思路:
    step1:实现一个迭代器对象weatherIterator,__next__方法每次返回一个城市气温
    step2:实现一个可迭代对象weatherIterable,__iter__方法返回一个迭代器对象
    代码:

    import requests
    # #[u'北京',u'上海',u'广州',u'长春']
    # print(getweather(u'杭州'))
    # print(getweather(u'南昌'))
    
    from collections import Iterable,Iterator
    
    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)   #r:<Response [200]>
            #print(r.json())
            data = r.json()['data']['forecast'][0]  #其中只有response返回为json格式时,用r.json()打印出响应的内容,
            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)   #返回一个迭代器对象
    
    if __name__=='__main__':
        for x in WeatherIterable([u'北京',u'上海',u'广州',u'长春',u'南昌']):  #这里用for循环来调用实际是调用可迭代对象的__iter__()方法,再调用迭代器对象的__next__()方法
            print(x)
    
    ===========================================================================================
    
    from collections import Iterable,Iterator
    import requests
    
    class WeatherIterator(Iterator):
        def __init__(self,cities):
            self.cities = cities
            self.index = 0 # 通过index来确定具体迭代哪个城市的气温信息
    
    
        def __next__(self):
            if self.index == len(self.cities):
                raise StopIteration
            city = self.cities[self.index]
            self.index += 1
            return self.get_weather(city)
    
        def get_weather(self,city):
            url = 'http://wthrcdn.etouch.cn/weather_mini?city=' + city
            r = requests.get(url)
            data = r.json()['data']['forecast'][0]
            return city, data['high'], data['low']
    
    class WeatherIterable(Iterable):
        def __init(self,cities):
            self.cities = cities
            
        def __iter__(self):
            return WeatherIterator(self.cities)
    
    def show(W):
        for x in W:
            print(x)
    
    # W = WeatherIterator(['北京','上海','广州'] * 10)
    W = WeatherIterator(['北京','上海','广州'] * 10)
    show(W)
    print('-'*20) # 若是直接使用迭代器对象进行迭代,则下面的无结果,因为是迭代器对象是一次性的消费
    show(W)
    
    ======================================================================================
    
    # 通过生成器来实现,可以自动维护迭代状态,无需定义itreator的类
    from collections import Iterable,Iterator
    import requests
    
    #class WeatherIterator(Iterator):
    #    def __init__(self,cities):
    #        self.cities = cities
    #        self.index = 0 # 通过index来确定具体迭代哪个城市的气温信息
    #
    #
    #    def __next__(self):
    #        if self.index == len(self.cities):
    #            raise StopIteration
    #        city = self.cities[self.index]
    #        self.index += 1
    #        return self.get_weather(city)
    #
    #    def get_weather(self,city):
    #        url = 'http://wthrcdn.etouch.cn/weather_mini?city=' + city
    #        r = requests.get(url)
    #        data = r.json()['data']['forecast'][0]
    #        return city, data['high'], data['low']
    #
    class WeatherIterable(Iterable):
        def __init__(self,cities):
            self.cities = cities
            
        def __iter__(self):
            for city in self.cities:
                yield self.get_weather(city)
                
        def get_weather(self,city):
            url = 'http://wthrcdn.etouch.cn/weather_mini?city=' + city
            r = requests.get(url)
            data = r.json()['data']['forecast'][0]
            return city, data['high'], data['low']
    
    def show(W):
        for x in W:
            print(x)
    
    W = WeatherIterable(['北京','上海','广州'] * 10)
    # W = WeatherIterator(['北京','上海','广州'] * 10)
    show(W)
    print('-'*20) # 若是直接使用迭代器对象进行迭代,则下面的无结果,因为是迭代器对象是一次性的消费
    show(W)
    
  • 相关阅读:
    BPM
    rust
    sql
    relational model
    C语言丨还没搞懂逻辑运算符?一篇文章教你区分“真假”!
    掉发不是病,秃起来真要命!作为程序猿的你,脱发了吗?
    什么是正确的编程观?从正确认识C语言开始!
    春运火车票如何安心购票?用C语言实现火车售票系统(源码分享)
    趣味编程丨如何用C语言输出杨辉三角?只需三步!
    2020年编程语言排行榜年终大盘点:C语言连续八个月蝉联第一,C++稳居第四
  • 原文地址:https://www.cnblogs.com/Richardo-M-Q/p/13263693.html
Copyright © 2011-2022 走看看