__iter __()实现为生成器

Ema*_*olm 8 python iterator generator dispatch

我有一个对象子类,它__ iter __使用缓存生成器实现动态调度(我还有一个使iter缓存无效的方法),如下所示:

def __iter__(self):
    print("iter called")
    if self.__iter_cache is None:
        iter_seen = {}
        iter_cache = []
        for name in self.__slots:
            value = self.__slots[name]
            iter_seen[name] = True
            item = (name, value)
            iter_cache.append(item)
            yield item           
        for d in self.__dc_list:
            for name, value in iter(d):
                if name not in iter_seen:
                    iter_seen[name] = True
                    item = (name, value)
                    iter_cache.append(item)
                    yield item
        self.__iter_cache = iter_cache
    else:
        print("iter cache hit")
        for item in self.__iter_cache:
            yield item
Run Code Online (Sandbox Code Playgroud)

它似乎工作......有没有我可能不知道的陷阱?我做的事情有多荒谬吗?

Mak*_*cha 5

container.__iter__()返回一个迭代器对象。迭代器对象本身需要支持以下两种方法,它们共同构成了迭代器协议:

iterator.__iter__()
Run Code Online (Sandbox Code Playgroud)

返回迭代器对象本身。

iterator.next()
Run Code Online (Sandbox Code Playgroud)

从容器中返回下一个项目。

这正是每个生成器所具有的。所以不要害怕任何副作用。

  • 通过使用一个或多个 `yield` 语句使容器对象的 `__iter__()` 方法成为生成器是一种常见的快捷方式,它避免了必须显式定义和编码单独的迭代器类及其方法。 (4认同)

jfs*_*jfs 3

这似乎是一种非常脆弱的方法。在活动迭代期间更改 __slots、__dc_list、__iter_cache 中的任何一个就足以将对象置于不一致状态。

您需要禁止在迭代期间更改对象,或者立即生成所有缓存项并返回列表的副本。