Python-生成器,其中无返回值

问题描述 投票:10回答:4

我有这样的生成器:

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并引发异常。

我该如何返回一个空的生成器?

python for-loop generator
4个回答
8
投票
def iterate_my_objects_if_something(self): if self.my_objects: for x in self.my_objects: if x.something: yield x

3
投票
if self.my_objects: for x in self.my_objects: if x.something: yield x

3
投票
哪个迭代会导致错误。这肯定是在追溯中指出的,但是在这种情况下,不需要追溯(请继续阅读)。

生成器上的迭代是否有问题?[看一下之后,这很明显,但是值得澄清:

    空生成器不属于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

    0
    投票
    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)
    
    © www.soinside.com 2019 - 2024. All rights reserved.