V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
jakeyfly
V2EX  ›  Python

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

  •  
  •   jakeyfly · 2017-12-04 14:09:48 +08:00 · 2165 次点击
    这是一个创建于 2553 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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 上买的视频 有几节课听的一头雾水 求大神指点
    14 条回复    2017-12-05 17:46:34 +08:00
    jakeyfly
        1
    jakeyfly  
    OP
       2017-12-04 14:13:38 +08:00
    贴代码 为啥显示出来 缩进都没了我 X
    fuge
        2
    fuge  
       2017-12-04 17:08:03 +08:00
    既然是花钱的视频有问题不是应该文卖家吗?
    GeruzoniAnsasu
        3
    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
        4
    jakeyfly  
    OP
       2017-12-04 18:35:11 +08:00
    @GeruzoniAnsasu 我把__iter__ 也写到 iterator 里面 不是就行了 我看网上也有这种写法 然后 关键是 iterable 这个类不写 直接实例化 iterator 这个类 效果是一模一样的 也就是说 最终起作用的只有) NEXT () 这个方法呀 我绕在这里好久了
    jakeyfly
        5
    jakeyfly  
    OP
       2017-12-04 18:37:55 +08:00
    好纠结 iterable 没用作用 或者说 我找不到他起作用的点 脑子想的有点疼
    jakeyfly
        6
    jakeyfly  
    OP
       2017-12-04 21:42:57 +08:00 via iPhone
    @fuge 说的有理啊 可是没人理我
    neoblackcap
        7
    neoblackcap  
       2017-12-04 23:11:03 +08:00
    简单来说,iterable 就是含__iter__方法的,它可不一定是 iterator,interator 是一个具体的对象,比如列表也是 iterable,但不是 iterator。
    还有一个理解就是 iterable 就是一个接口,iterator 是一个实现了 iterable 接口的对象。
    jakeyfly
        8
    jakeyfly  
    OP
       2017-12-04 23:58:41 +08:00
    @neoblackcap 这些我并不是想不明白 ,只是上面那个 iterable 类 没起作用 有点想不通。
    GeruzoniAnsasu
        9
    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
        10
    jakeyfly  
    OP
       2017-12-05 17:01:37 +08:00
    @GeruzoniAnsasu v2 果然有大神 太感谢了 我好好消化一下
    jakeyfly
        11
    jakeyfly  
    OP
       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
        12
    jakeyfly  
    OP
       2017-12-05 17:32:58 +08:00
    @GeruzoniAnsasu 这个例子的意思是 迭代器 是按指针走的? ZIP 作用于同一个迭代器 其实是在一个迭代器内部走?
    jakeyfly
        13
    jakeyfly  
    OP
       2017-12-05 17:40:36 +08:00
    原理是因为 NEXT()方法想明白了,但是想不明白的是跟 我上面那个例子的联系。。。
    jakeyfly
        14
    jakeyfly  
    OP
       2017-12-05 17:46:34 +08:00
    我现在理解的是 iterator 是用来操作 iterable 的 是这样吗? 我最先看到上面那组代码的时候 的印象是 iterablev 那个类是多余的,现在看来 iterator 那个类是干活的 iterable 那个类是容器 怪不得用他来实例话 我这样理解对吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2785 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 12:48 · PVG 20:48 · LAX 04:48 · JFK 07:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.