Python 定义支持两个或多个同时迭代的iterable类

Python 定义支持两个或多个同时迭代的iterable类,python,iterator,Python,Iterator,我不确定这个标题是否好,希望有人能帮我改一下 我试图定义一个分子类,希望它能遍历原子。 我搜索了人们如何定义iterable类,它可能是这样的: class molecule(object): def __init__(self,name): self.__pointer=0 # ...something else def __iter__(self): self.__pointer=0 return sel

我不确定这个标题是否好,希望有人能帮我改一下

我试图定义一个
分子
类,希望它能遍历原子。 我搜索了人们如何定义iterable类,它可能是这样的:

class molecule(object):
    def __init__(self,name):
         self.__pointer=0
         # ...something else
    def __iter__(self):
         self.__pointer=0
         return self
    def __next__(self):
         self.__pointer+=1
         if self.__pointer<=self.natoms: # self.natoms is defined somewhere
               return self[self.__pointer]   # suppose __getitem__ is defined to return an atom object
         else:
               raise StopIteration("Exceeded all atoms")
然而,我发现它不能在两个迭代器中工作,如果它们同时存在的话

>>> ite=iter(ben)
>>> next(ite)
# atom1
>>> next(ite)
# atom2
>>> ite2=iter(ben)
>>> next(ite)
# atom1 again, where atom3 is expected
>>> next(ite2)
# atom2, where atom1 is expected
这并不奇怪,因为这两个迭代器共享一个相同的
self.\u指针
,因此定义一个新的迭代器会将指针更新为零

我看了这一页,他们中的大多数人在课堂上使用了一个
self.\u指针
,这就引出了我的问题。 我想如果
指针
是迭代器(
ite
ite2
)的属性,而不是迭代对象本身(
molecular
),那么这个问题就可以解决了


希望有人能给你一些帮助:)谢谢。

每次调用迭代器对象时,让它返回新的迭代器对象

class molecule_iterator(object):
    def __init__(self, obj):
        self.pointer = 0
        self.obj = obj

    def __next__(self):
        self.pointer += 1  # Are you sure to do this here?
        if self.pointer < self.obj.natoms:
            return self.obj[self.pointer]
        raise StopIteration()


class molecule(object):
    ...

    def __iter__(self):
        return molecule_iterator(self)

    ...

演示:

>使
\uuuu iter\uuu
每次调用新的迭代器对象时都返回它@RuixingWang,我更新了答案以包含第一个选项的代码。(返回新的迭代器实例)很酷的答案。对于注释
#你确定吗
,是的,因为我从1开始计算原子,但不是零:)谢谢!
class molecule_iterator(object):
    def __init__(self, obj):
        self.pointer = 0
        self.obj = obj

    def __next__(self):
        self.pointer += 1  # Are you sure to do this here?
        if self.pointer < self.obj.natoms:
            return self.obj[self.pointer]
        raise StopIteration()


class molecule(object):
    ...

    def __iter__(self):
        return molecule_iterator(self)

    ...
def __iter__(self):
    for i in range(self.natoms):
        yield self[i + 1]