我正在尝试将自定义类从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'
”。
我在这里缺少什么?
答案 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