传入json对象_【Python基础】可迭代对象&迭代器对象及其实现

14d9406bbb31c8973f259f1f69ee8e76.png

可迭代对象

461aad1517771abbf2048303e13a63d1.png

首选确保for循环的in后面是一个可迭代对象,这样就能通过python内置函数iter()得到一个迭代器对象(iterator)

b81d5e145c5869431bf549559e4745c9.png

23d43d68574faf4140ffee03f931230f.png

我们分别把列表list_test和字符串str_test分别得到一个迭代器 我们尝试传入数字看看

c48182e96ae46cb43d4b6d8a8c3d2b5d.png

这里抛出了异常,因为数字不是一个可迭代对象

那么问题来了, 为什么列表和字符串是可迭代对象? 因为这些对象满足了特殊的接口:

a60e61b7844fcb249c99588af2d89406.png

迭代列表时候,我们看看了列表下__开头的方法,其中的__iter__()就是迭代协议的接口。我们在使用iter(list_test)时候实际内部调用了这个__iter__()函数 我们再看迭代字符串时候,我们发现没有找到__iter__() , 但是有__getIterm__()这个接口

619e7de2065d01deaf54bf876d9f8ba4.png

我们再看看迭代的签名, 要么传入的参数(对象)本身有迭代器,要么是一个序列。 我们这里list__test本身就有迭代器,而str_test是有__getItem__这种序列的接口。

43eaed7f9206de47fcfb895ad90e708c.png

迭代器对象

c8729ef3f47aa7ff5d8f78d9129162cb.png

for n in list_test:     print(n)

所以我们就搞清楚了,for循环中先由iter(list_test)得到一个迭代器t,然后不停的调用next next next 直到捕获到一个StopIteration 异常,跳出循环。这就是for循环的工作流程

案例实现

我们从天气应用抓取各个城市温度:北京: 10~18 南京:18~ 23 上海: 14~22 .... 如果一次性抓取所有天气再显示,显示一个城市气温时,会有很多延迟。 并且浪费存储空间。  我们希望以“用时访问”的策略,能把所有城市气温封装到一个对象里面,需要时候再显示。 提示, 可用for语句进行迭代。  代码怎么实现?

解决思路

  1. 实现一个迭代器对象Weatherlterator, next方法每次返回一个城市气温.(迭代完毕时候要抛出停止迭代异常)

  1. 实现一个可迭代对象Weatherlterable, __iter__方法返回一个迭代器对象。

def getWeather(city):    r = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=' + city)    data = r.json()['data']['forecast'][0]    # print(data)    return '%s: %s, %s'%(city, data['low'], data['high'])print(getWeather(u'南京'))print(getWeather(u'上海'))

2dfbc1185d0b8e42dd692aaa37868ffe.png

以上是获取城市气温数据方法,下面我们实现迭代器对象和可迭代对象,在python标准库中对他们的接口已经有定义。

5ac70dc98139de6d78454b560cd6162b.png

在collections包下有

  • Iterable(可迭代对象抽象接口就是__iter__)

  • Iterator(迭代器抽象接口就是__next__)

我们可以直接继承这两个抽象类

import requestsfrom collections import Iterable, Iterator# 天气迭代器,class WeatherIterator(Iterator):    # 应该有个参数描述此迭代器能够返回哪些城市信息, 传入一个城市名字符串列表cities    def __init__(self, cities):        self.cities = cities        # 记录迭代的位置,初始化为0        self.index = 0    def getWeather(self, city):        r = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=' + city)        data = r.json()['data']['forecast'][0]        # print(data)        return '%s: %s, %s' % (city, data['low'], data['high'])    # 迭代器对象需要实现next接口, 需要返回一个城市基本信息,全部迭代完成时候需要抛出异常    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)# 使用时候,实例化# [u'南京', u'上海', u'北京', u'深圳']for city in WeatherIterable([u'南京', u'上海', u'北京', u'深圳']):    print(city)

4d11cbe7f2fceb2226b897c7110c5b9f.png

这里我们就实现了一个可迭代对象和迭代器对象,并且用示例感受了某些需要惰性访问场景使用他们的优势。

查看仓库可直接获取源码:

 https://github.com/AlexZ33/Python_basic/blob/main/%E5%8F%AF%E8%BF%AD%E4%BB%A3%E5%AF%B9%E8%B1%A1%26%E8%BF%AD%E4%BB%A3%E5%99%A8%E5%AF%B9%E8%B1%A1/getWeather.py

❤️爱心三连击

1.看到这里了就点个在看支持下吧,你的「点赞,在看是我们创作的动力。

2.关注公众号图灵编程俱乐部

 回复「沙龙」参加线上线下技术沙龙; 回复「python」参加python训练营; 回复「java」参加2020版企业实战Java精英线下课程; 回复「图灵编程」了解图灵IT青年俱乐部;

3.也可添加微信【17612567626】,一起成长。

309d5344a07782982ba227c65d7c2fe5.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值