Python 迭代器自定义类,包装在OrderedDict上,对下一步感到困惑__
我意识到我仍然不太理解如何实现迭代器类。因此,一个类可以对其某些内容进行“for循环” 我已经看过这些答案(我仍然不明白): 据我所知,iterable是一个实现Python 迭代器自定义类,包装在OrderedDict上,对下一步感到困惑__,python,python-3.x,iteration,Python,Python 3.x,Iteration,我意识到我仍然不太理解如何实现迭代器类。因此,一个类可以对其某些内容进行“for循环” 我已经看过这些答案(我仍然不明白): 据我所知,iterable是一个实现\uuuuu iter\uuuuuu并返回迭代器的函数,迭代器是已实现\uuuu next\uuuuu的函数。 从这一点上,我不知何故理解了,如果我希望我的类是一个迭代器,并且是iterable。我必须定义\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu以返回self,并定义\uuuuuuuuuuuuuuu
\uuuuu iter\uuuuuu
并返回迭代器的函数,迭代器是已实现\uuuu next\uuuuu
的函数。
从这一点上,我不知何故理解了,如果我希望我的类是一个迭代器,并且是iterable。我必须定义\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
以返回self,并定义\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。到目前为止我错了吗
这是我班的脚手架:
class Wrapper:
def __init__(self, low, high):
self.store = OrderedDict() # it is imported (ommited)
def __getitem__(self, key):
return self.store[key]
def __iter__(self):
return self
# Option 3
return self.store
def __next__(self):
# Option 1
for key in self.store:
return key
# Option 2
for key in self.store.keys():
return key
尝试了上述选项,但均无效:(
发生的事情是我准备了一些py.tests来测试迭代是否正确,只是一个简单的for循环,没有什么特别的。测试只是永远运行(或者比我的耐心<5分钟更长),但是mock类有5个项,所以不会花太长时间
我做错了什么?您可以进行以下更改:
class Wrapper:
def __init__(self, low, high):
self.store = OrderedDict()
self.__iter = None # maintain state of self as iterator
def __iter__(self):
if self.__iter is None:
self.__iter = iter(self.store)
return self
def __next__(self):
try:
return next(self.__iter)
except StopIteration: # support repeated iteration
self.__iter = None
raise
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法应返回self
,以正确实现协议。这可确保在循环期间调用next
将迭
for x in wrapper:
# do stuff with x
next(wrapper) # skip one
在大多数情况下,插入\uuuu iter\uuu
就足够了:
class Wrapper:
def __init__(self, low, high):
self.store = OrderedDict()
def __iter__(self):
return iter(self.store)
您可以进行以下更改:
class Wrapper:
def __init__(self, low, high):
self.store = OrderedDict()
self.__iter = None # maintain state of self as iterator
def __iter__(self):
if self.__iter is None:
self.__iter = iter(self.store)
return self
def __next__(self):
try:
return next(self.__iter)
except StopIteration: # support repeated iteration
self.__iter = None
raise
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法应返回self
,以正确实现协议。这可确保在循环期间调用next
将迭
for x in wrapper:
# do stuff with x
next(wrapper) # skip one
在大多数情况下,插入\uuuu iter\uuu
就足够了:
class Wrapper:
def __init__(self, low, high):
self.store = OrderedDict()
def __iter__(self):
return iter(self.store)
你说,你的概念搞混了
我意识到我仍然不太理解如何实现一个迭代器类。因此,一个可以对其某些内容进行“for循环”的类
但事情不是这样的。如果您只想在类的实例上执行for
循环,几乎可以肯定的是,您不应该让实例直接成为迭代器。您应该编写一个\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法,手动或通过yield
ing返回迭代器,而不应该编写\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu下一步
:
# Returning an iterator manually:
class Wrapper:
...
def __iter__(self):
return iter(self.store)
# or with yield:
class Wrapper:
...
def __iter__(self):
for thing in self.store:
yield thing
迭代器在技术上是可迭代的,但只能使用一次。要编写迭代器,您必须\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
返回self
,并在每次调用时\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.我将在半开放区间[0,10]上编写迭代器,因为为OrderedICT编写迭代器只会将所有内容委托给OrderedICT的迭代器,因为这太直接了,不具有指导意义:
class Iterator:
def __init__(self):
self.state = 0
def __iter__(self):
return self
def __next__(self):
if self.state == 10:
raise StopIteration
self.state += 1
return self.state - 1
但是,即使您确实需要迭代器,手动编写迭代器也是不寻常的;使用yield
:
def iterator():
for i in range(10):
yield i
# or managing the index manually, to show what it would be like without range:
def iterator():
i = 0
while i < 10:
yield i
i += 1
def迭代器():
对于范围(10)内的i:
产量一
#或者手动管理索引,以显示没有范围时的情况:
def迭代器():
i=0
当我<10时:
产量一
i+=1
你的概念混淆了。你说
我意识到我仍然不太理解如何实现一个迭代器类。因此,一个可以对其某些内容进行“for循环”的类
但事情不是这样的。如果您只想在类的实例上执行for
循环,几乎可以肯定的是,您不应该让实例直接成为迭代器。您应该编写一个\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法,手动或通过yield
ing返回迭代器,而不应该编写\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu下一步
:
# Returning an iterator manually:
class Wrapper:
...
def __iter__(self):
return iter(self.store)
# or with yield:
class Wrapper:
...
def __iter__(self):
for thing in self.store:
yield thing
迭代器在技术上是可迭代的,但只能使用一次。要编写迭代器,您必须\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
返回self
,并在每次调用时\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.我将在半开放区间[0,10]上编写迭代器,因为为OrderedICT编写迭代器只会将所有内容委托给OrderedICT的迭代器,因为这太直接了,不具有指导意义:
class Iterator:
def __init__(self):
self.state = 0
def __iter__(self):
return self
def __next__(self):
if self.state == 10:
raise StopIteration
self.state += 1
return self.state - 1
但是,即使您确实需要迭代器,手动编写迭代器也是不寻常的;使用yield
:
def iterator():
for i in range(10):
yield i
# or managing the index manually, to show what it would be like without range:
def iterator():
i = 0
while i < 10:
yield i
i += 1
def迭代器():
对于范围(10)内的i:
产量一
#或者手动管理索引,以显示没有范围时的情况:
def迭代器():
i=0
当我<10时:
产量一
i+=1
谢谢,这工作得很好。在没有状态维护的情况下,它似乎也能工作。您能解释一下为什么需要它吗?您可以在包装器中为x执行(隐式调用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu),但是下一个(包装器)
(隐式调用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu如果不维护状态,则无法正常工作。\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
和\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu迭代器协议。因为这个类定义了迭代器,\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>必须返回self
。很可能,OPmethod@user2357112你到底是什么意思?是的我的类定义是错误的,但Schwobasegll解决方案似乎使它工作得非常完美。谢谢,这项工作