使用next迭代器添加到类列表

时间:2015-11-27 08:51:20

标签: python iterator next

我有点困惑为什么这个代码第一次工作,但是在后续调用中 - 下一个返回bool而不是列表中的对象或者引发异常。
Python 2.6.6(r266:84292,2013年11月21日,10:50:32)

class report:
    title="Sample title"
    def __init__(self,rundate,runuser=""):
        self.rundate = rundate
        self.user = runuser
        self.systems = []

    def addNodeReport(self,systemname,reponame,nodename,result):
        try:
            sys = next(x.name == systemname for x in self.systems)
        except StopIteration:
            sys = system(systemname) # additional class
            self.systems.append(sys)
        finally:
            print sys # added for testing
            sys.addReport(reponame,nodename,result)
>>> from report import report
>>> r = report("20151127")
>>> r.addNodeReport("testsystem1","scripts","testhost1","All fine")
<report.system instance at 0x1c5b908>
>>> r.addNodeReport("testsystem1","scripts","testhost2","All fine")
True
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "report.py", line 44, in addNodeReport
    sys.addReport(reponame,nodename,result)
AttributeError: 'bool' object has no attribute 'addReport'

1 个答案:

答案 0 :(得分:1)

你应该阅读有关生成器表达式的内容,它不能按你的意愿工作。

在第一次运行期间,sys = next(x.name == systemname for x in self.systems)因“StopIteration为空而立即失败并显示self.systems”。在except部分,sys分配了一个report.system对象。

在第二次运行期间sys = next(x.name == systemname for x in self.systems)评估为sys = True,因为这正是生成器所做的。

sys = next(x.name == systemname for x in self.systems)
# is equivalent to
if self.systems:
    x = self.systems[0]  # next function takes the first value of the list
    sys = (x.name == systemname)  # here sys becomes a boolean value
else:
    raise StopIteration

所以基本上x.name == systemname for x in self.systems会创建一个生成器,每次调用True时都会生成Falsenext。 (或nextfor in循环中)隐式调用{/ 1}}

如果您想要使用名称为systemname的所有系统,请使用filter

systems = filter(lambda x: x.name == systemname, self.systems)
for sys in systems:
    do_stuff()