【问题标题】:iter() returned non-iterator of type 'dict_items'iter() 返回“dict_items”类型的非迭代器
【发布时间】:2018-09-29 03:42:28
【问题描述】:

这让我发疯了。下面是我正在搞砸的class,目标是有一种方法来支持动态属性分配。 请暂时忘记糟糕的实现或为什么我不只使用字典,我知道还有其他方法可以做到这一点(例如Enum)但这是我之前的测试代码现在我的任务是找出它为什么不起作用。

class Family(object):
    def children(self):
        return self.__dict__.values()

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __getitem__(self, item):
        return self.__dict__[item]

    def __repr__(self):
        return str(self.__dict__)

    def __iter__(self):
        return self.__dict__.items()

这一切看起来都很好,我启动了一个测试对象如下:

foo = Family()
foo.a = 'foo'
foo.b = 'bar'

[i for i in foo]

现在预期的结果是[('a', 'foo'), ('b', 'bar')],但我得到的是这个:

TypeError: iter() returned non-iterator of type 'dict_items'

我认为我可能搞砸了__iter__ 方法,所以我检查如下:

type(foo.__iter__())
# <class 'dict_items'>
type(foo.__dict__.items())
# <class 'dict_items'>

[i for i in foo.__dict.__items()]
# [('a', 'foo'), ('b', 'bar')]

foo.__dict__.items() == foo.__iter__()
# True

如果它们都相同,为什么[i for i in foo] 不起作用?

【问题讨论】:

  • 顺便说一句,为了完整起见,您还应该定义一个 __delitem__ 方法。

标签: python python-3.x class


【解决方案1】:

这个呢:

def __iter__(self):
    return iter(self.__dict__.items())

Python 需要 iterator,而不是 list(或其他类似列表/类似字典的对象)

记住:listdict 不是iteratoriterator 通常是(为了便于理解)指向listdict 的项目的指针(光标) .

【讨论】:

  • FWIW,在 Python 3 中,dict.items() 返回 view object,而不是列表。
  • 这行得通。我以为我已经尝试过了,但我一定错过了。我觉得很愚蠢,但是为什么[i for i in foo.__dict__.items()] 会起作用呢?是否在.items() 上隐式调用iter?我已经离开 Python 有一段时间了,所以感觉有点缺乏。
  • @Idlehands 正确。 for 调用 iter 你给它的迭代。
猜你喜欢
  • 1970-01-01
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-10
  • 1970-01-01
  • 2014-02-02
  • 2013-09-23
相关资源
最近更新 更多