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
flowarmor
V2EX  ›  Python

迭代器内的变量是怎么保存的?

  •  
  •   flowarmor · 2018-02-17 00:55:48 +08:00 · 3695 次点击
    这是一个创建于 2232 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有下面一段代码,分别打印 1 1 2 3 5 和 0 0 0 0 0,请问后面一个迭代器为什么不会打印 0 1 2 3 4 ?

    class Fib(object):
        def __init__(self):
            self.prev = 0
            self.curr = 1
        def next(self):
            value = self.curr
            self.curr += self.prev
            self.prev = value
            return value
        def __iter__(self):
            return self
    
    class T(object):
        def __iter__(self):
            return self
        def next(self):
            for i in range(5):
                return i
    
    f = Fib()
    t = T()
    
    print next(f)
    print next(f)
    print next(f)
    print next(f)
    print next(f)
    
    print next(t)
    print next(t)
    print next(t)
    print next(t)
    print next(t)
    
    第 1 条附言  ·  2018-02-17 13:39:51 +08:00
    已结,大半夜大脑短路问了这么个问题。
    12 条回复    2018-02-23 17:07:02 +08:00
    quinoa42
        1
    quinoa42  
       2018-02-17 01:23:35 +08:00
    因为已经 return 了,后面 i=1,2,3,4 根本不会运行
    wwqgtxx
        2
    wwqgtxx  
       2018-02-17 01:25:45 +08:00 via iPhone
    yield 才是给迭代器用的
    KKKKKK
        3
    KKKKKK  
       2018-02-17 01:50:51 +08:00 via Android
    查一查 magic method

    Next 调用的是 __next__ 这个方法
    lrxiao
        4
    lrxiao  
       2018-02-17 03:09:59 +08:00
    generator_instance.gi_frame.f_locals
    flowarmor
        5
    flowarmor  
    OP
       2018-02-17 12:53:55 +08:00
    @quinoa42 但是第一个 Fib 的实例就运行了。
    flowarmor
        6
    flowarmor  
    OP
       2018-02-17 12:54:38 +08:00
    @wwqgtxx 迭代器只要求有 next 和__iter__,yield 是给生成器函数用的。
    flowarmor
        7
    flowarmor  
    OP
       2018-02-17 12:54:56 +08:00
    @KKKKKK __next__是 Python 3 的方法,Python 2 的叫 next。
    ch3nOr
        8
    ch3nOr  
       2018-02-17 13:23:57 +08:00
    #1 说的对,每次你用 next(t) 的時候,就調用一次 t.next()。你可以在[這裏]( http://pythontutor.com/visualize.html) 寫下你的代碼,可視化你的執行步驟。
    wallriding
        9
    wallriding  
       2018-02-17 13:24:50 +08:00
    for i in range(5):
    return i

    楼主你再看看?
    ch3nOr
        10
    ch3nOr  
       2018-02-17 13:25:19 +08:00
    Fib 的話,記錄了當前迭代的狀態,所以完全沒問題
    flowarmor
        11
    flowarmor  
    OP
       2018-02-17 13:39:24 +08:00
    @wallriding 嗯哼,昨夜太困大脑短路了。
    frostming
        12
    frostming  
       2018-02-23 17:07:02 +08:00
    @flowarmor
    迭代器只要求有 next 和__iter__,yield 是给生成器函数用的。

    一般也是用 yield 实现 next,用 return 不是不行,多麻烦啊
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1001 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 22:18 · PVG 06:18 · LAX 15:18 · JFK 18:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.