基礎(chǔ)復(fù)習(xí):
可迭代對象:滿足了迭代協(xié)議的一個(gè)接口__iter__
或者 __getitem__
迭代器對象:滿足了迭代協(xié)議的__next__
接口
__next__
:可以得到迭代器中的下一個(gè)元素啸罢,最后一個(gè)元素被取出后崎脉,會拋出StopIteration異常
for循環(huán)工作機(jī)制:
1 由iter()方法得到一個(gè)迭代器
2.不停地調(diào)用next()方法,直到捕獲一個(gè)StopIteration異常逐样,退出循環(huán)
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.
# 可以由可迭代對象得到一個(gè)迭代器
l = [1,2,3,4]
print(iter(l)) # <list_iterator object at 0x000002D7D2D7B208>
print(l.__iter__()) # <list_iterator object at 0x000001E6BE719198>
問題拋出:
如何實(shí)現(xiàn)可迭代對象和迭代器對象
實(shí)際案例:
某軟件要求篡腌,從網(wǎng)絡(luò)抓取各個(gè)城市的氣溫信息热某,并以此顯示:
北京:15-20
天津:17-22
長春:12-18
....
如果一次抓取所有的城市天氣再顯示转捕,顯示第一個(gè)城市氣溫時(shí),有很高的延時(shí)耗式,并且浪費(fèi)存儲空間胁住。
我們期望以“用時(shí)訪問”策略,并且能把所有的城市氣溫封裝到一個(gè)對象里刊咳,可用for語句進(jìn)行迭代彪见,如何解決?
解決方案:
1.實(shí)現(xiàn)一個(gè)迭代器對象WeatherIterator,next方法每次返回一個(gè)氣溫
2.實(shí)現(xiàn)一個(gè)可迭代對象WeatherIterable娱挨,iter方法返回一個(gè)迭代器對象
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℃
"""