我有这样的生成器:
def iterate_my_objects_if_something(self):
for x in self.my_objects:
if x.something:
yield x
我这样称呼:
for x in self.iterate_my_objects_if_something():
pass
在没有任何要返回的情况下,这将尝试遍历NoneType并引发异常。
我该如何返回一个空的生成器?
def iterate_my_objects_if_something(self):
if self.my_objects:
for x in self.my_objects:
if x.something:
yield x
if self.my_objects:
for x in self.my_objects:
if x.something:
yield x
生成器上的迭代是否有问题?[看一下之后,这很明显,但是值得澄清:
NoneType
,因此对其进行迭代将不会导致此类问题:>>> def test_generator():
for i in []:
yield i
>>> list(test_generator()) # proof it is empty
[]
>>> for x in test_generator():
pass
>>>
[generator在定义期间被Python识别(我正在简化),尝试将生成器和简单函数混合(例如,通过使用条件,如下所示)将是语法错误:
>>> def test_generator_2(sth):
if sth:
for i in []:
yield i
else:
return []
SyntaxError: 'return' with argument inside generator (<pyshell#73>, line 6)
迭代
inside生成器是否有问题?基于以上结论,错误不是关于迭代器的迭代,而是创建它时发生的事情(生成器中的代码):
def iterate_my_objects_if_something(self): for x in self.my_objects: # <-- only iteration inside generator if x.something: yield x
因此,在某些情况下,self.my_objects
变成None
。
解决方案要解决该问题之一:
确保
self.my_objects
始终是可迭代的(例如,空列表[]
),或
def iterate_my_objects_if_something(self):
# checks, if value is None, otherwise assumes iterable:
if self.my_objects is not None:
for x in self.my_objects:
if x.something:
yield x
def iterate_my_objects_if_something(self):
if not self.my_objects:
raise StopIteration
for x in self.my_objects:
if x.something:
yield x
我会更进一步:
def iterate_my_objects_if_something(self):
if not self.my_objects:
raise StopIteration
yeild from (x for x in self.my_objects if x.something)