Python 3中自定义类的迭代器

时间:2018-02-06 11:58:48

标签: python python-3.x dictionary iterator

我正在尝试将自定义类从Python 2移植到Python 3.我无法找到正确的语法来移植类的迭代器。这是真正的类的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)

在上面的代码中,iteritems()在Python 3中断。根据this高度评价的答案,“dict.items现在在{2}中完成了dict.iteritems”。所以我接下来试了一下:

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

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

根据this回答,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

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

我在这里缺少什么?

2 个答案:

答案 0 :(得分:4)

如果我理解正确,您只需将项目作为迭代器

返回即可
class Temp:
    def __init__(self):
        self.d = {'1':1,'2':2}
    def __iter__(self):
        return iter(self.d.items())

使您的类可迭代。 或者像这样写一个生成器:

def __iter__(self):
    for key,item in self.d.items():
        yield key,item

如果你想能够分别迭代键和项目,即以通常的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()

我从你的措辞中猜测,如果不需要,你实际上并不希望实施next()方法。如果你愿意,你将不得不以某种方式将你的整个类变成一个迭代器,并以某种方式跟踪你在迭代器中的瞬间,因为字典本身不是迭代器。另请参阅this答案。

答案 1 :(得分:1)

我不知道Python 2中有什么用。但是在Python 3上,使用generator之类的东西最容易创建迭代器。我提供名称和链接,以便您可以进一步研究。

class Temp:
    def __init__(self):
        self.d = {}
    def __iter__(self):
        for thing in self.d.items():
            yield thing