实现可迭代对象与迭代器对象
在写爬虫的时候我们需要将爬取出来的内容先封装到一个对象中,然后再用for语句循环迭代出来数据,而不是将抓取出来的数据一次性的显示,因为这样既浪费存储空间而且由于网络IO处理起来还慢,这时候就需要用到迭代器了。
from collections import Iterable, Iterator
import requests
class WeatherIterator(Iterator):
def __init__(self, caties):
self.caties = caties
self.index = 0
def __next__(self):
if self.index == len(self.caties):
raise StopIteration
city = self.caties[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 = WeatherIterable(['北京', '上海', '广州'] * 10)
show(w)
使用生成器函数实现可迭代对象
一个模拟案例:实现一个可迭代对象的类,使它能迭代出给定范围内所有的质数。
from collections import Iterable
class PrimeNumbers(Iterable):
def __init__(self, a, b):
self.a = a
self.b = b
def __iter__(self):
for k in range(self.a, self.b + 1):
if self.is_prime(k):
yield k
def is_prime(self, k):
return False if k < 2 else all(map(lambda x: k % x, range(2, k)))
pn = PrimeNumbers(1, 30)
for n in pn:
print(n)
自己实现反向迭代
功能类似于将range
的步进值
设置为正数时为正向迭代,设置为负数时为反向迭代。
from decimal import Decimal
class FloatRange:
def __init__(self, a, b, step):
self.a = Decimal(str(a))
self.b = Decimal(str(b))
self.step = Decimal(str(step))
def __iter__(self):
t = self.a
while t <= self.b:
yield float(t)
t += self.step
def __reversed__(self):
t = self.b
while t >= self.a:
yield float(t)
t -= self.step
fr = FloatRange(3.0, 4.0, 0.2)
for x in fr:
print(x)
print('-' * 20)
for x in reversed(fr):
print(x)
"""
4.0
--------------------
4.0
3.8
3.6
3.4
3.2
3.0
"""