Python遍历非序列对象

16

我有这样一段代码,它创建一个笔记并添加到笔记本中。但是,当我运行它时,会出现“遍历非序列”的错误。

import datetime
class Note:
    def __init__(self, memo, tags):
        self.memo = memo
        self.tags = tags
        self.creation_date = datetime.date.today()

def __str__(self):
    return 'Memo={0}, Tag={1}'.format(self.memo, self.tags)


class NoteBook:
     def __init__(self):
        self.notes = []

     def add_note(self,memo,tags):
        self.notes.append(Note(memo,tags))

if __name__ == "__main__":
    firstnote = Note('This is my first memo','example')
    print(firstnote)
    Notes = NoteBook()
    Notes.add_note('Added thru notes','example-1')
    Notes.add_note('Added thru notes','example-2')
    for note in Notes:
        print(note.memo)

错误:

C:\Python27\Basics\OOP\formytesting>python notebook.py  
Memo=This is my first memo, Tag=example  
Traceback (most recent call last):  
  File "notebook.py", line 27, in   
    for note in Notes:  
TypeError: iteration over non-sequence

1
你应该提供准确的错误信息以及出现错误的位置。最好的方法是发布完整的回溯消息。提供的信息越多,获得的帮助就越好。 - Levon
作为一条提示:你应该显式地从object继承:class NoteBook(object):,这就是所谓的新式类。有关详细信息,请参见此问题 - Adam Parkin
4个回答

13

您试图迭代对象本身,这导致出现错误。您想要迭代对象内部的列表,在这种情况下是 Notes.notes(这是有些混淆的命名方式,您可能希望通过为笔记本对象实例使用另一个名称来区分内部列表)。

for note in Notes.notes:
    print(note.memo)

9

Notes是NoteBook的一个实例。要遍历这样的对象,它需要一个__iter__方法

class NoteBook:

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

PS. 在Python中,使用小写字母变量名来表示类的实例是PEP8 的建议和约定,而用驼峰命名法表示类名。

遵循这个惯例有助于立即区分您的类实例和类。

如果您希望遵循这个惯例(并赢得其他喜欢这个惯例的人的好感),请将Notes更改为notes


__iter__ 中使用 yield 和仅使用 return iter(self.notes) 有何好处? - Adam Parkin
同意@AdamParkin的观点。为什么要重新发明轮子,当你可以把工作交给已经内置了它的对象呢?请查看我的答案以获取该实现。 - Jordan
1
可能有些偏题,抱歉我要讲究一下,你所说的通常被称为帕斯卡命名法:NoteBookMyClassNameJavaScript。驼峰命名法是指首字母小写,例如 Java 类名(如果我没记错的话):noteBookmyClassNamejQuery - Yvonne Aburrow

2
如果你想要对Notes本身进行迭代,你也可以为其添加一个自定义的__iter__方法,并返回.notes属性。
class Notebook:

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

    ...

最好使用while循环来产生结果。 - Angry 84
不是这样的。迭代器会在内部处理这个问题。 - Jordan

1
问题出在这一行: for note in Notes: ,因为Notes是一个对象而不是列表。我认为你想要 for note in Notes.notes: 同时,正如unutbu所指出的,您可以重载__iter__运算符,这将允许您当前的循环工作。这取决于您希望这个外观如何。就个人而言,我会重载__iter__

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接