看了个视频关于可迭代对象与可迭代对象的 有一个问题没搞懂 代码如下

2017-12-04 14:09:48 +08:00
 jakeyfly
import requests
from collections import Iterable, Iterator
import json

class WeaherIterator(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 WeaherIterable(Iterable):
def __init__(self,cities):
self.cities = cities

def __iter__(self):
return WeaherIterator(self.cities)

for x in WeaherIterable(['北京','上海', '长沙', '福州', '广州', '长春', '厦门']):
print(x)

WeaherIterable 类到底做了什么 没搞懂 我直接用 WeaherIterator 效果是一样的 。为啥要 WeaherIterable 实例传给 WeaherIterator 呢 视频上是说 这样可以延迟显示 有一个显示一个 但是我看直接用 WeaherIterator 也不是一下子显示出来的 也是一个个出来的 。这个 IMOC 上买的视频 有几节课听的一头雾水 求大神指点
2177 次点击
所在节点    Python
14 条回复
jakeyfly
2017-12-04 14:13:38 +08:00
贴代码 为啥显示出来 缩进都没了我 X
fuge
2017-12-04 17:08:03 +08:00
既然是花钱的视频有问题不是应该文卖家吗?
GeruzoniAnsasu
2017-12-04 18:20:43 +08:00
Python 里的可迭代对象 iterable 和迭代器 iterator 令人迷惑得厉害
总的来说
迭代器 iterator 是可迭代对象 iterable 的 访问器
迭代器 iterator 原本应该是一个指针,也就说应该具有 iterator->obj::*这种语义,同时迭代器迭代位置还能移动,调用 iterator.__next__()能获取被迭代对象的下一个元素
iterable 保证能返回一个用于访问其内容的迭代器(或者随机访问器__getitem__),一般 iterable 是某种容器,容器中内容具体如何组织我们不关心,我们只关心怎么取出来然后怎么用,而组织“怎么取”,就是迭代器要做的工作

iterable 不仅包括迭代器关心的那些元素,还包括很多很多其它的东西,比如你可以把整个 v 站视为可迭代的,给它定义一个专门的迭代器对象用来浏览每一个帖子,当你 for 帖子 in v 站的时候这个迭代器帮你遍历所有帖子,但你还可以 v 站.refresh(),v 站.down(),v 站.block(uid)什么的,当你不需要遍历 iterable 的时候,iterable 本身还有很多其它的属性和方法
jakeyfly
2017-12-04 18:35:11 +08:00
@GeruzoniAnsasu 我把__iter__ 也写到 iterator 里面 不是就行了 我看网上也有这种写法 然后 关键是 iterable 这个类不写 直接实例化 iterator 这个类 效果是一模一样的 也就是说 最终起作用的只有) NEXT () 这个方法呀 我绕在这里好久了
jakeyfly
2017-12-04 18:37:55 +08:00
好纠结 iterable 没用作用 或者说 我找不到他起作用的点 脑子想的有点疼
jakeyfly
2017-12-04 21:42:57 +08:00
@fuge 说的有理啊 可是没人理我
neoblackcap
2017-12-04 23:11:03 +08:00
简单来说,iterable 就是含__iter__方法的,它可不一定是 iterator,interator 是一个具体的对象,比如列表也是 iterable,但不是 iterator。
还有一个理解就是 iterable 就是一个接口,iterator 是一个实现了 iterable 接口的对象。
jakeyfly
2017-12-04 23:58:41 +08:00
@neoblackcap 这些我并不是想不明白 ,只是上面那个 iterable 类 没起作用 有点想不通。
GeruzoniAnsasu
2017-12-05 09:41:07 +08:00
@jakeyfly
你摆出来的这个例子并没有很好提现 iterable 和对应 iterator 的关系所以你没啥感觉
一个类确实可以同时实现 next 和 iter 两个内置方法,典型的你看 generator 对象就能被获取 iterator,也能调用 next,但对它自己调用 next 还是获取迭代器去访问它内部的元素,意义是完全不一样的

但从逻辑和结构上来说,iterable 是容器,iterator 是访问器,它们的功能就是不一样的。比如现在迭代器已经指向了容器中的某个位置,然后你需要把这个位置信息传递给其它方法去处理,那你肯定希望函数参数传的是一个迭代器,而不需要把原来的整个容器一并传进来;如果还不是很理解,下面这个不很好的例子起码能体现出区别

instance = MyIterable([1,2,3,4,5,6,7,8,9,10])#MyIterable 是随便什么 iterable 类
it = iter(instance)

print( *zip( it,it ) )
print( *zip( instance,instance ) )
print( *zip( *[iter(instance)]*2 ) )
jakeyfly
2017-12-05 17:01:37 +08:00
@GeruzoniAnsasu v2 果然有大神 太感谢了 我好好消化一下
jakeyfly
2017-12-05 17:12:47 +08:00
@GeruzoniAnsasu
instance =[1,2,3,4]#MyIterable 是随便什么 iterable 类
it = iter(instance)

print( *zip( it,it ) )
print( *zip( instance,instance ) )
print( *zip( *[iter(instance)]*2 ) )

结果
(1, 2) (3, 4)
(1, 1) (2, 2) (3, 3) (4, 4)
(1, 2) (3, 4)

为什么这样呢 不是很懂
jakeyfly
2017-12-05 17:32:58 +08:00
@GeruzoniAnsasu 这个例子的意思是 迭代器 是按指针走的? ZIP 作用于同一个迭代器 其实是在一个迭代器内部走?
jakeyfly
2017-12-05 17:40:36 +08:00
原理是因为 NEXT()方法想明白了,但是想不明白的是跟 我上面那个例子的联系。。。
jakeyfly
2017-12-05 17:46:34 +08:00
我现在理解的是 iterator 是用来操作 iterable 的 是这样吗? 我最先看到上面那组代码的时候 的印象是 iterablev 那个类是多余的,现在看来 iterator 那个类是干活的 iterable 那个类是容器 怪不得用他来实例话 我这样理解对吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/411811

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX