- 主题:关于for in的简单实现
你实现了一个错误的__iter__方法,它应该返回一个迭代器对象而不是调用__next__。
其次,你在实现__next__时使用了yield关键字,这意味着它实际上是一个生成器函数,而不是__next__方法的正确实现。
next直接返回值就行,不用实现iter
【 在 poggy 的大作中提到: 】
:
: 下面能够实现循环, 但是, 有个小问题, 就是循环完毕, 按照规范__next__ 应该抛出StopIteration
: 但奇怪的是for in 并没有对这个异常做处理, 而是继续抛出来了, 是这个异常不对吗?
: 如果, 去掉这个raise, 只是简单返回好像就不出错了。
:
#发自zSMTH@CDU.MP
--
FROM 171.120.158.*
我建议你阅读Python文档中的术语表。
对于你给出的第二段代码,它是一个标准的迭代器其中iter返回self,next被反复调用返回值。
包含yield的函数被称为生成器,其返回值是生成器迭代器。其中不应当引发任何异常,如果你引发stopiteration,则会产生一个Runtime Error。还有for else 很少用,建议不要使用。
第一个例子中你的用法是错误用法,它没有实现迭代器,如果其他人调用next(obj)不能得到期望的结果。
我建议你重新学习基础内容
【 在 poggy 的大作中提到: 】
:
: 【 在 poggy 的大作中提到: 】
: :
: : 您需要再多学习学习基础知识,:)
: : 生成器函数本身就是一种特殊的迭代器。
#发自zSMTH@CDU.MP
--
FROM 171.120.158.*
【 在 poggy 的大作中提到: 】
:
: 【 在 VincentGe 的大作中提到: 】
: : 我建议你阅读Python文档中的术语表。
: : 对于你给出的第二段代码,它是一个标准的迭代器其中iter返回self,next被反复调用返回值。
: : 包含yield的函数被称为生成器,其返回值是生成器迭代器。其中不应当引发任何异常,如果你引发stopiteration,则会产生一个Runtime Error。还有for else 很少用,建议不要使用。
我认为我很清楚,朋友,是你在这方面有问题。
可迭代对象不一定是迭代器,一个迭代器对象要求__iter__必须返回自身,实现了__next__对象才能是迭代器。生成器函数的返回值是生成器迭代器。
你错误的使用了__next__方法,你的第一方案会导致异常,请你重复调用next,你会发现你的迭代器无法终止。
另我建议你将你的内容置于上方,否则我的客户端无法正确引用你的回答
#发自zSMTH@CDU.MP
--
FROM 171.120.158.*
我并无恶意,我也是来讨论问题。
for in 对应的是可迭代对象,它会调用__iter__,得到一个可迭代对象,如果这个对象是迭代器,它会调用迭代器的 __next__方法,系统会自行处理Stop iteration异常。
也就是说,__next__是用来实现迭代器的,你将__next__写为一个生成器后,得到的是一个生成器迭代器,在生成器迭代器里引发Stopiteration 会产生一个 RuntimerError异常
: ...................
我到这里是来讨论问题的, 我一开始标题就告知, 在讨论 for in的实现问题,
__iter__ 当然可以返回迭代器对象, 而且, 返回迭代器是for in的大多数实现,
但是, 如果你仔细看规范, for 循环并不要求是迭代器对象,
而是更宽泛的, Iterable, 而且, 使用生成函数, 自由度更高。
#发自zSMTH@CDU.MP
--
FROM 171.120.158.*
抱歉,现在我理解你的需求了。但,方法名字很重要。
你希望用生成器和__iter__来实现 for i in obj。
第一方案你实现的是可迭代对象iterable,而不是迭代器,迭代器要求实现__next__,且__iter__一定要返回self。
至于那个Stopiteration 异常为什么for in没有处理,因为那个异常是由于你Raise Stopiteration 引发的RuntimeError,而不是Stopiteration。
至于最后一点,名字很重要,如果你把__next__换成其他名字我大概率就不会说这些,一般看来,你实现一个魔术方法,我便认为你在实现一个迭代器,所以引发了哪些误解。
【 在 poggy 的大作中提到: 】
: 我认为是你以为我的理解是错误的, 说明你还是没明白我帖子的意思
: 我已经和你说了一遍了, 我是要实现for in 循环, 并使用生成器函数, 就这么简单一个需求。
: 你张嘴一个这错了, 闭嘴一个这错了, 还不够添乱的
: 我的第一个方案是仿照迭代器实现生成器, 是有点不伦不类,否则,我也不会奇怪发帖子。
: 后面, 我自己给出了, 一个通常迭代器的 __iter__ __next__的实现。
: 之后, 我自己也试出来生成函数的实现, 只要__iter__ 里面返回一个生成函数就够了, 至于生成函数用什么名字,
: 并不重要, 也就是 把 __next__换成个普通名字的函数也一样。
: 这样 for x in obj
: 就会被翻译成 调用obj.__iter__ 返回一个生成函数, for 会对生成函数反复调用来yield到正确的值。
#发自zSMTH@CDU.MP
--
FROM 171.120.158.*