首選確保for循環的in後面是一個可迭代對象,這樣就能通過python內置函數iter()得到一個迭代器對象(iterator)
我們分別把列表list_test和字符串str_test分別得到一個迭代器 我們嘗試傳入數字看看
這裡拋出了異常,因為數字不是一個可迭代對象
那麼問題來了, 為什麼列表和字符串是可迭代對象? 因為這些對象滿足了特殊的接口:
迭代列表時候,我們看看了列表下__開頭的方法,其中的__iter__()就是迭代協議的接口。我們在使用iter(list_test)時候實際內部調用了這個__iter__()函數 我們再看迭代字符串時候,我們發現沒有找到__iter__() , 但是有__getIterm__()這個接口
我們再看看迭代的籤名, 要麼傳入的參數(對象)本身有迭代器,要麼是一個序列。 我們這裡list__test本身就有迭代器,而str_test是有__getItem__這種序列的接口。
迭代器對象for n in list_test: print(n)所以我們就搞清楚了,for循環中先由iter(list_test)得到一個迭代器t,然後不停的調用next next next 直到捕獲到一個StopIteration 異常,跳出循環。這就是for循環的工作流程
案例實現我們從天氣應用抓取各個城市溫度:北京: 10~18 南京:18~23 上海: 14~22 .... 如果一次性抓取所有天氣再顯示,顯示一個城市氣溫時,會有很多延遲。並且浪費存儲空間。 我們希望以「用時訪問」的策略,能把所有城市氣溫封裝到一個對象裡面,需要時候再顯示。提示, 可用for語句進行迭代。 代碼怎麼實現?解決思路
實現一個迭代器對象Weatherlterator, next方法每次返回一個城市氣溫.(迭代完畢時候要拋出停止迭代異常)
實現一個可迭代對象Weatherlterable, __iter__方法返回一個迭代器對象。
def getWeather(city): r = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=' + city) data = r.json()['data']['forecast'][0] return '%s: %s, %s'%(city, data['low'], data['high'])
print(getWeather(u'南京'))print(getWeather(u'上海'))以上是獲取城市氣溫數據方法,下面我們實現迭代器對象和可迭代對象,在python標準庫中對他們的接口已經有定義。
在collections包下有
我們可以直接繼承這兩個抽象類
import requestsfrom collections import Iterable, Iterator
class WeatherIterator(Iterator): def __init__(self, cities): self.cities = cities self.index = 0
def getWeather(self, city): r = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=' + city) data = r.json()['data']['forecast'][0] 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)
for city in WeatherIterable([u'南京', u'上海', u'北京', u'深圳']): print(city)這裡我們就實現了一個可迭代對象和迭代器對象,並且用示例感受了某些需要惰性訪問場景使用他們的優勢。
查看倉庫可直接獲取源碼:
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】,一起成長。