在Python中产生突破

根据这个问题的答案,C#中的yield break相当于在python中返回。 在正常情况下,“返回”确实停止了发电机。 但是,如果你的函数什么都不做,只能返回,你将得到一个None不是一个空的迭代器,它是通过在C#

def generate_nothing(): return for i in generate_nothing(): print i 

你会得到一个TypeError:'NoneType'对象是不可迭代的。 但是如果我在返回之前添加一个永不退出的yield,这个函数返回我所期望的。

 def generate_nothing(): if False: yield None return 

如果工作,但似乎有线。 谁有更好的主意?

谢谢,

处理这个问题的一个好方法就是提高StopIteration ,当你的迭代器没有剩余的时候会产生StopIteration ,并调用next() 。 这也将优雅地摆脱循环执行循环内没有任何循环。

例如,给定一个元组(0, 1, 2, 3)我想得到重叠对((0, 1), (1, 2), (2, 3)) 。 我可以这样做:

 def pairs(numbers): if len(numbers) < 2: raise StopIteration for i, number in enumerate(numbers[1:]): yield numbers[i], number 

现在可以安全地处理1个或更less的列表。

 def generate_nothing(): return yield 
 def generate_nothing(): return iter([]) 

有趣的是两个函数都有相同的字节码。 当字节码编译器findyield关键字时,可能会有一个标志设置为generator

 >>> def f(): ... return >>> def g(): ... if False: yield #in Python2 you can use 0 instead of False to achieve the same result >>> from dis import dis >>> dis(f) 2 0 LOAD_CONST 0 (None) 3 RETURN_VALUE >>> dis(g) 2 0 LOAD_CONST 0 (None) 3 RETURN_VALUE