Python 3中自定义类的迭代器

Att*_*nen 4 python dictionary iterator python-3.x

我试图将自定义类从Python 2移植到Python3。我找不到正确的语法来移植该类的迭代器。这是真实类的MVCE,到目前为止我仍在尝试解决此问题:

工作的Python 2代码:

class Temp:
    def __init__(self):
        self.d = dict()
    def __iter__(self):
        return self.d.iteritems()

temp = Temp()
for thing in temp:
    print(thing)
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,iteritems()在Python 3中中断。根据这个广受好评的答案,“ dict.items现在dict.iteritems在python 2中做了事情”。所以我接下来尝试了:

class Temp:
    def __init__(self):
        self.d = dict()
    def __iter__(self):
        return self.d.items()
Run Code Online (Sandbox Code Playgroud)

上面的代码产生“ TypeError: iter() returned non-iterator of type 'dict_items'

根据答案,Python 3除了iter方法之外,还需要可迭代的对象提供next()方法。好吧,字典也是可迭代的,因此在我的用例中,我应该能够只传递字典的next和iter方法,对吗?

class Temp:
    def __init__(self):
        self.d = dict()
    def __iter__(self):
        return self.d.__iter__
    def next(self):
        return self.d.next
Run Code Online (Sandbox Code Playgroud)

这次给了我“ TypeError: iter() returned non-iterator of type 'method-wrapper'”。

我在这里想念什么?

Ban*_*ana 5

如果我理解正确,则可以将项目作为迭代器返回

class Temp:
    def __init__(self):
        self.d = {'1':1,'2':2}
    def __iter__(self):
        return iter(self.d.items())
Run Code Online (Sandbox Code Playgroud)

使您的课程变得可迭代。或者像这样编写一个生成器:

def __iter__(self):
    for key,item in self.d.items():
        yield key,item
Run Code Online (Sandbox Code Playgroud)

如果您希望能够分别遍历键和项,即以常规python3字典可以的形式进行遍历,则可以使用如下附加功能:

class Temp:
    def __init__(self, dic):
        self.d = dic

    def __iter__(self):
        return iter(self.d)

    def keys(self):
        return self.d.keys()

    def items(self):
        return self.d.items()

    def values(self):
        return self.d.values()
Run Code Online (Sandbox Code Playgroud)

从您的措辞方式猜测,您实际上并不想在next()不需要时实施该方法。如果愿意,您将不得不以某种方式将整个类变成一个迭代器,并以某种方式跟踪您在该迭代器中的当前位置,因为字典本身不是迭代器。另请参阅答案。