我有点困惑为什么这个代码第一次工作,但是在后续调用中 - 下一个返回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'
答案 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
时都会生成False
或next
。 (或next
在for in
循环中)隐式调用{/ 1}}
如果您想要使用名称为systemname
的所有系统,请使用filter
:
systems = filter(lambda x: x.name == systemname, self.systems)
for sys in systems:
do_stuff()